diff --git a/conf.json b/conf.json new file mode 100644 index 00000000..aab9c0a1 --- /dev/null +++ b/conf.json @@ -0,0 +1,5 @@ +{ + "plugins": [ + "./plugin/md" + ] +} \ No newline at end of file diff --git a/jsdoc.js b/jsdoc.js new file mode 100644 index 00000000..36d520dc --- /dev/null +++ b/jsdoc.js @@ -0,0 +1,51 @@ +// like: java -classpath ~/Scripts/js.jar org.mozilla.javascript.tools.shell.Main jsdoc.js examples/test1.js +// or: node jsdoc examples/test1.js + +(function() { + + // normalise rhino + if (typeof load !== 'undefined') { + load('lib/rhino-shim.js'); + } + + // global modules + global._ = require('underscore'); + _.mixin(require('underscore.string')); + global.signals = require('signals'); + + // needed modules + var fs = require('fs'), + opts = require('jsdoc/options').parse( process.argv.slice(2) ), + dumper = require('jsdoc/util/dumper'); + + // user configuration + try { + var conf = JSON.parse( + fs.readFileSync('./conf.json', 'utf-8') + ); + } + catch (e) { + throw('Configuration file cannot be evaluated. '+e); + } + + if (typeof conf.plugins !== 'undefined') { + for (var i = 0, len = conf.plugins.length; i < len; i++) { + require(conf.plugins[i]); + } + } + + if (opts.help) { + console.log('USAGE: node main.js yourfile.js'); + process.exit(0); + } + var srcFile = opts._[0]; + + var src = fs.readFileSync(srcFile, 'utf-8'); + + var parser = require('jsdoc/parser'); + + var symbols = parser.parse(src); + + console.log( dumper.dump(symbols) ); + +})(); \ No newline at end of file diff --git a/lib/json.js b/lib/json.js new file mode 100644 index 00000000..ae21742e --- /dev/null +++ b/lib/json.js @@ -0,0 +1,238 @@ +// This source code is free for use in the public domain. +// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + +// http://code.google.com/p/json-sans-eval/ + +/** + * Parses a string of well-formed JSON text. + * + * If the input is not well-formed, then behavior is undefined, but it is + * deterministic and is guaranteed not to modify any object other than its + * return value. + * + * This does not use `eval` so is less likely to have obscure security bugs than + * json2.js. + * It is optimized for speed, so is much faster than json_parse.js. + * + * This library should be used whenever security is a concern (when JSON may + * come from an untrusted source), speed is a concern, and erroring on malformed + * JSON is *not* a concern. + * + * Pros Cons + * +-----------------------+-----------------------+ + * json_sans_eval.js | Fast, secure | Not validating | + * +-----------------------+-----------------------+ + * json_parse.js | Validating, secure | Slow | + * +-----------------------+-----------------------+ + * json2.js | Fast, some validation | Potentially insecure | + * +-----------------------+-----------------------+ + * + * json2.js is very fast, but potentially insecure since it calls `eval` to + * parse JSON data, so an attacker might be able to supply strange JS that + * looks like JSON, but that executes arbitrary javascript. + * If you do have to use json2.js with untrusted data, make sure you keep + * your version of json2.js up to date so that you get patches as they're + * released. + * + * @param {string} json per RFC 4627 + * @param {function (this:Object, string, *):*} opt_reviver optional function + * that reworks JSON objects post-parse per Chapter 15.12 of EcmaScript3.1. + * If supplied, the function is called with a string key, and a value. + * The value is the property of 'this'. The reviver should return + * the value to use in its place. So if dates were serialized as + * {@code { "type": "Date", "time": 1234 }}, then a reviver might look like + * {@code + * function (key, value) { + * if (value && typeof value === 'object' && 'Date' === value.type) { + * return new Date(value.time); + * } else { + * return value; + * } + * }}. + * If the reviver returns {@code undefined} then the property named by key + * will be deleted from its container. + * {@code this} is bound to the object containing the specified property. + * @return {Object|Array} + * @author Mike Samuel + */ +var jsonParse = (function () { + var number + = '(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)'; + var oneChar = '(?:[^\\0-\\x08\\x0a-\\x1f\"\\\\]' + + '|\\\\(?:[\"/\\\\bfnrt]|u[0-9A-Fa-f]{4}))'; + var string = '(?:\"' + oneChar + '*\")'; + + // Will match a value in a well-formed JSON file. + // If the input is not well-formed, may match strangely, but not in an unsafe + // way. + // Since this only matches value tokens, it does not match whitespace, colons, + // or commas. + var jsonToken = new RegExp( + '(?:false|true|null|[\\{\\}\\[\\]]' + + '|' + number + + '|' + string + + ')', 'g'); + + // Matches escape sequences in a string literal + var escapeSequence = new RegExp('\\\\(?:([^u])|u(.{4}))', 'g'); + + // Decodes escape sequences in object literals + var escapes = { + '"': '"', + '/': '/', + '\\': '\\', + 'b': '\b', + 'f': '\f', + 'n': '\n', + 'r': '\r', + 't': '\t' + }; + function unescapeOne(_, ch, hex) { + return ch ? escapes[ch] : String.fromCharCode(parseInt(hex, 16)); + } + + // A non-falsy value that coerces to the empty string when used as a key. + var EMPTY_STRING = new String(''); + var SLASH = '\\'; + + // Constructor to use based on an open token. + var firstTokenCtors = { '{': Object, '[': Array }; + + var hop = Object.hasOwnProperty; + + return function (json, opt_reviver) { + // Split into tokens + var toks = json.match(jsonToken); + // Construct the object to return + var result; + var tok = toks[0]; + var topLevelPrimitive = false; + if ('{' === tok) { + result = {}; + } else if ('[' === tok) { + result = []; + } else { + // The RFC only allows arrays or objects at the top level, but the JSON.parse + // defined by the EcmaScript 5 draft does allow strings, booleans, numbers, and null + // at the top level. + result = []; + topLevelPrimitive = true; + } + + // If undefined, the key in an object key/value record to use for the next + // value parsed. + var key; + // Loop over remaining tokens maintaining a stack of uncompleted objects and + // arrays. + var stack = [result]; + for (var i = 1 - topLevelPrimitive, n = toks.length; i < n; ++i) { + tok = toks[i]; + + var cont; + switch (tok.charCodeAt(0)) { + default: // sign or digit + cont = stack[0]; + cont[key || cont.length] = +(tok); + key = void 0; + break; + case 0x22: // '"' + tok = tok.substring(1, tok.length - 1); + if (tok.indexOf(SLASH) !== -1) { + tok = tok.replace(escapeSequence, unescapeOne); + } + cont = stack[0]; + if (!key) { + if (cont instanceof Array) { + key = cont.length; + } else { + key = tok || EMPTY_STRING; // Use as key for next value seen. + break; + } + } + cont[key] = tok; + key = void 0; + break; + case 0x5b: // '[' + cont = stack[0]; + stack.unshift(cont[key || cont.length] = []); + key = void 0; + break; + case 0x5d: // ']' + stack.shift(); + break; + case 0x66: // 'f' + cont = stack[0]; + cont[key || cont.length] = false; + key = void 0; + break; + case 0x6e: // 'n' + cont = stack[0]; + cont[key || cont.length] = null; + key = void 0; + break; + case 0x74: // 't' + cont = stack[0]; + cont[key || cont.length] = true; + key = void 0; + break; + case 0x7b: // '{' + cont = stack[0]; + stack.unshift(cont[key || cont.length] = {}); + key = void 0; + break; + case 0x7d: // '}' + stack.shift(); + break; + } + } + // Fail if we've got an uncompleted object. + if (topLevelPrimitive) { + if (stack.length !== 1) { throw new Error(); } + result = result[0]; + } else { + if (stack.length) { throw new Error(); } + } + + if (opt_reviver) { + // Based on walk as implemented in http://www.json.org/json2.js + var walk = function (holder, key) { + var value = holder[key]; + if (value && typeof value === 'object') { + var toDelete = null; + for (var k in value) { + if (hop.call(value, k) && value !== holder) { + // Recurse to properties first. This has the effect of causing + // the reviver to be called on the object graph depth-first. + + // Since 'this' is bound to the holder of the property, the + // reviver can access sibling properties of k including ones + // that have not yet been revived. + + // The value returned by the reviver is used in place of the + // current value of property k. + // If it returns undefined then the property is deleted. + var v = walk(value, k); + if (v !== void 0) { + value[k] = v; + } else { + // Deleting properties inside the loop has vaguely defined + // semantics in ES3 and ES3.1. + if (!toDelete) { toDelete = []; } + toDelete.push(k); + } + } + } + if (toDelete) { + for (var i = toDelete.length; --i >= 0;) { + delete value[toDelete[i]]; + } + } + } + return opt_reviver.call(holder, key, value); + }; + result = walk({ '': result }, ''); + } + + return result; + }; +})(); \ No newline at end of file diff --git a/lib/nodeunit.js b/lib/nodeunit.js new file mode 100644 index 00000000..df267910 --- /dev/null +++ b/lib/nodeunit.js @@ -0,0 +1,1761 @@ +/*! + * Nodeunit + * https://github.com/caolan/nodeunit + * Copyright (c) 2010 Caolan McMahon + * MIT Licensed + * + * json2.js + * http://www.JSON.org/json2.js + * Public Domain. + * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + */ +nodeunit = (function(){ +/* + http://www.JSON.org/json2.js + 2010-11-17 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, strict: false, regexp: false */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (!this.JSON) { + this.JSON = {}; +} + +(function () { + "use strict"; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? + '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ +.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') +.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') +.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); +var assert = {}; +var types = {}; +var core = {}; +var nodeunit = {}; +var reporter = {}; +(function(){ + + var async = {}; + + // global on the server, window in the browser + var root = this; + var previous_async = root.async; + + if(typeof module !== 'undefined' && module.exports) module.exports = async; + else root.async = async; + + async.noConflict = function(){ + root.async = previous_async; + return async; + }; + + //// cross-browser compatiblity functions //// + + var _forEach = function(arr, iterator){ + if(arr.forEach) return arr.forEach(iterator); + for(var i=0; i b ? 1 : 0; + }), function(x){return x.value;})); + }) + }; + + async.auto = function(tasks, callback){ + callback = callback || function(){}; + var keys = _keys(tasks); + if(!keys.length) return callback(null); + + var completed = []; + + var listeners = []; + var addListener = function(fn){ + listeners.unshift(fn); + }; + var removeListener = function(fn){ + for(var i=0; i +// +// 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 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. + + +var pSlice = Array.prototype.slice; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = exports; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({message: message, actual: actual, expected: expected}) + +assert.AssertionError = function AssertionError (options) { + this.name = "AssertionError"; + this.message = options.message; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } +}; +// code from util.inherits in node +assert.AssertionError.super_ = Error; + + +// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call +// TODO: test what effect this may have +var ctor = function () { this.constructor = assert.AssertionError; }; +ctor.prototype = Error.prototype; +assert.AssertionError.prototype = new ctor(); + + +assert.AssertionError.prototype.toString = function() { + if (this.message) { + return [this.name+":", this.message].join(' '); + } else { + return [ this.name+":" + , JSON.stringify(this.expected ) + , this.operator + , JSON.stringify(this.actual) + ].join(" "); + } +}; + +// assert.AssertionError instanceof Error + +assert.AssertionError.__proto__ = Error.prototype; + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +assert.ok = function ok(value, message) { + if (!!!value) fail(value, true, message, "==", assert.ok); +}; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, "==", assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, "!=", assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, "deepEqual", assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3. Other pairs that do not both pass typeof value == "object", + // equivalence is determined by ==. + } else if (typeof actual != 'object' && typeof expected != 'object') { + return actual == expected; + + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical "prototype" property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isUndefinedOrNull (value) { + return value === null || value === undefined; +} + +function isArguments (object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv (a, b) { + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical "prototype" property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try{ + var ka = _keys(a), + kb = _keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key] )) + return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, "===", assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as determined by !==. +// assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, "!==", assert.notStrictEqual); + } +}; + +function _throws (shouldThrow, block, err, message) { + var exception = null, + threw = false, + typematters = true; + + message = message || ""; + + //handle optional arguments + if (arguments.length == 3) { + if (typeof(err) == "string") { + message = err; + typematters = false; + } + } else if (arguments.length == 2) { + typematters = false; + } + + try { + block(); + } catch (e) { + threw = true; + exception = e; + } + + if (shouldThrow && !threw) { + fail( "Missing expected exception" + + (err && err.name ? " ("+err.name+")." : '.') + + (message ? " " + message : "") + ); + } + if (!shouldThrow && threw && typematters && exception instanceof err) { + fail( "Got unwanted exception" + + (err && err.name ? " ("+err.name+")." : '.') + + (message ? " " + message : "") + ); + } + if ((shouldThrow && threw && typematters && !(exception instanceof err)) || + (!shouldThrow && threw)) { + throw exception; + } +}; + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert['throws'] = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function (err) { if (err) {throw err;}}; +})(assert); +(function(exports){ +/*! + * Nodeunit + * Copyright (c) 2010 Caolan McMahon + * MIT Licensed + * + * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! + * Only code on that line will be removed, its mostly to avoid requiring code + * that is node specific + */ + +/** + * Module dependencies + */ + + + +/** + * Creates assertion objects representing the result of an assert call. + * Accepts an object or AssertionError as its argument. + * + * @param {object} obj + * @api public + */ + +exports.assertion = function (obj) { + return { + method: obj.method || '', + message: obj.message || (obj.error && obj.error.message) || '', + error: obj.error, + passed: function () { + return !this.error; + }, + failed: function () { + return Boolean(this.error); + } + }; +}; + +/** + * Creates an assertion list object representing a group of assertions. + * Accepts an array of assertion objects. + * + * @param {Array} arr + * @param {Number} duration + * @api public + */ + +exports.assertionList = function (arr, duration) { + var that = arr || []; + that.failures = function () { + var failures = 0; + for (var i=0; i'; +}; + + +/** + * Run all tests within each module, reporting the results + * + * @param {Array} files + * @api public + */ + +exports.run = function (modules, options) { + var start = new Date().getTime(); + exports.addStyles(); + + var html = ''; + nodeunit.runModules(modules, { + moduleStart: function (name) { + html += '

' + name + '

'; + html += '
    '; + }, + testDone: function (name, assertions) { + if (!assertions.failures()) { + html += '
  1. ' + name + '
  2. '; + } + else { + html += '
  3. ' + name; + for (var i=0; i'; + } + html += '
    ';
    +                        html += a.error.stack || a.error;
    +                        html += '
    '; + } + }; + html += '
  4. '; + } + }, + moduleDone: function () { + html += '
'; + }, + done: function (assertions) { + var end = new Date().getTime(); + var duration = end - start; + if (assertions.failures()) { + html += '

FAILURES: ' + assertions.failures() + + '/' + assertions.length + ' assertions failed (' + + assertions.duration + 'ms)

'; + } + else { + html += '

OK: ' + assertions.length + + ' assertions (' + assertions.duration + 'ms)

'; + } + if (typeof document === 'undefined' && typeof print !== 'undefined') { + return print( html.replace(/
  • /g, '\033[1;032m√ \033[0m').replace(/
  • /g, '\033[1;031mX \033[0m').replace(//g, "\n").replace(/<\/h\d>/g, "\n").replace(/
    /g, "\n ").replace(/<\/(li|div)>/g, "\n").replace(/<[^>]+?>/g, '') ); + } + document.body.innerHTML += html; + } + }); +}; +})(reporter); +nodeunit = core; +nodeunit.assert = assert; +nodeunit.reporter = reporter; +nodeunit.run = reporter.run; +return nodeunit; })(); \ No newline at end of file diff --git a/lib/rhino-require.js b/lib/rhino-require.js new file mode 100644 index 00000000..2de9bbb7 --- /dev/null +++ b/lib/rhino-require.js @@ -0,0 +1,253 @@ +/* + Rhino-Require is Public Domain + + + The author or authors of this code dedicate any and all copyright interest + in this code to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and successors. We + intend this dedication to be an overt act of relinquishment in perpetuity of + all present and future rights to this code under copyright law. + */ + +(function() { + + var require = global.require = function(id) { /*debug*///console.log('require('+id+')'); + var moduleContent = '', + moduleUri; + + moduleUri = require.resolve(id); + moduleContent = ''; + + var file = new java.io.File(moduleUri); + try { + var scanner = new java.util.Scanner(file).useDelimiter("\\Z"); + moduleContent = String( scanner.next() ); + } + catch(e) { + throw 'Unable to read file at: '+moduleUri+', '+e; + } + + if (moduleContent) { + try { + var f = new Function('require', 'exports', 'module', moduleContent), + exports = require.cache[moduleUri] || {}, + module = { id: id, uri: moduleUri, exports: exports }; + + + require._root.unshift(moduleUri); + f.call({}, require, exports, module); + require._root.shift(); + } + catch(e) { + throw 'Unable to require source code from "' + moduleUri + '": ' + e.toSource(); + } + + exports = module.exports || exports; + require.cache[id] = exports; + } + else { + throw 'The requested module cannot be returned: no content for id: "' + id + '" in paths: ' + require.paths.join(', '); + } + + return exports; + } + require._root = ['']; + require.paths = []; + require.cache = {}; // cache module exports. Like: {id: exported} + + /** Given a module id, try to find the path to the associated module. + */ + require.resolve = function(id) { + // TODO: 1. load node core modules + + // 2. dot-relative module id, like './foo/bar' + var parts = id.match(/^(\.?\.\/|\/)(.+)$/), + isRelative = false, + isAbsolute = false, + basename = id; + + if (parts) { + isRelative = parts[1] === './' || parts[1] === '../'; + isAbsolute = parts[1] === '/'; + basename = parts[2]; + } + + if (typeof basename !== 'undefined') { + + if (isAbsolute) { + rootedId = id; + } + else { + var root = (isRelative? toDir(require._root[0] || '.') : '.'), + rootedId = (root + '/' + id).replace(/\/[^\/]+\/\.\.\//g, '/').replace(/\/\.\//g, '/'), + uri = ''; + } + + if ( uri = loadAsFile(rootedId) ) { } + else if ( uri = loadAsDir(rootedId) ) { } + else if ( uri = loadNodeModules(rootedId) ) { } + else if ( uri = nodeModulesPaths(rootedId, 'rhino_modules') ) { } + else if ( uri = nodeModulesPaths(rootedId, 'node_modules') ) { } + + if (uri !== '') return toAbsolute(uri); + + throw 'Require Error: Not found.'; + } + } + + /** Given a path, return the base directory of that path. + @example toDir('/foo/bar/somefile.js'); => '/foo/bar' + */ + function toDir(path) { + var file = new java.io.File(path); + + if (file.isDirectory()) { + return path; + } + + var parts = path.split(/[\\\/]/); + parts.pop(); + + return parts.join('/'); + } + + /** Returns true if the given path exists and is a file. + */ + function isFile(path) { + var file = new java.io.File(path); + + if (file.isFile()) { + return true; + } + + return false; + } + + /** Returns true if the given path exists and is a directory. + */ + function isDir(path) { + var file = new java.io.File(path); + + if (file.isDirectory()) { + return true; + } + + return false; + } + + /** Get the path of the current working directory + */ + function getCwd() { + return toDir( ''+new java.io.File('.').getAbsolutePath() ).replace(/\/\.$/, ''); + } + + function toAbsolute(relPath) { + absPath = ''+new java.io.File(relPath).getAbsolutePath(); + absPath = absPath.replace(/\/[^\/]+\/\.\.\//g, '/').replace(/\/\.\//g, '/'); + return absPath; + } + + /** Assume the id is a file, try to find it. + */ + function loadAsFile(id) { + if ( isFile(id) ) { return id; } + + if ( isFile(id+'.js') ) { return id+'.js'; } + + if ( isFile(id+'.node') ) { throw 'Require Error: .node files not supported'; } + } + + /** Assume the id is a directory, try to find a module file within it. + */ + function loadAsDir(id) { + if (!isDir(id)) { + return; + } + // look for the "main" property of the package.json file + if ( isFile(id+'/package.json') ) { + var packageJson = readFileSync(id+'/package.json', 'utf-8'); + eval( 'packageJson = '+ packageJson); + if (packageJson.hasOwnProperty('main')) { + var main = (id + '/' + packageJson.main).replace(/\/\.?\//g, '/'); + return require.resolve(main); + } + } + + if ( isFile(id+'/index.js') ) { + return id+'/index.js'; + } + } + + function loadNodeModules(id) { + var path, + uri; + for (var i = 0, len = require.paths.length; i < len; i++) { + path = require.paths[i]; + if (isDir(path)) { + path = (path + '/' + id).replace(/\/\.?\//g, '/'); + + uri = loadAsFile(path); + if (typeof uri !== 'undefined') { + return uri; + } + + uri = loadAsDir(path); + if (typeof uri !== 'undefined') { + return uri; + } + } + } + } + + function nodeModulesPaths(id, moduleFolder) { + var cwd = getCwd(), + dirs = cwd.split('/'), + dir, + path, + filename, + uri; + + while (dirs.length) { + dir = dirs.join('/'); + path = dir+'/'+moduleFolder; + + if ( isDir(path) ) { + filename = (path+'/'+id).replace(/\/\.?\//g, '/'); + + if ( uri = loadAsFile(filename) ) { + uri = uri.replace(cwd, '.'); + return uri; + } + + if ( uri = loadAsDir(filename) ) { + uri = uri.replace(cwd, '.'); + return uri; + } + } + + dirs.pop(); + } + } + + function readFileSync(filename, encoding, callback) { + if (typeof arguments[1] === 'function') { + encoding = null; + callback = arguments[1]; + } + + encoding = encoding || java.lang.System.getProperty('file.encoding'); + + try { + var content = new java.util.Scanner( + new java.io.File(filename), + encoding + ).useDelimiter("\\Z"); + + return String( content.next() ); + } + catch (e) { + return ''; + } + } + +})(); \ No newline at end of file diff --git a/lib/rhino-shim.js b/lib/rhino-shim.js new file mode 100644 index 00000000..263c0727 --- /dev/null +++ b/lib/rhino-shim.js @@ -0,0 +1,69 @@ +global = this; + +load('lib/Rhino-Require/src/require.js'); + +(function(rhinoArgs) { + var dumper; + global.console = { + log: function(/*...*/) { + var args = Array.prototype.slice.call(arguments, 0), + dumper = dumper || require('jsdoc/util/dumper'); + + for (var i = 0, len = args.length; i < len; i++) { + if (typeof args[i] !== 'string') { + args[i] = dumper.dump(args[i]); + } + } + + print( args.join(' ') ); + } + }; + + global.process = { + exit: function(n) { + n = n || 0; + java.lang.System.exit(n); + }, + argv: [null, null].concat( Array.prototype.slice.call(rhinoArgs, 0) ) + }; + + if (typeof JSON === 'undefined') { // JSON is defined in Rhino 1.7+ + load('lib/json.js'); + global.JSON = { + parse: function(raw) { + return jsonParse(raw); + }, + stringify: function(o) { + return ''+ o; + } + } + } + + (function () { + var counter = 1; + var timeoutIds = {}; + + global.setTimeout = function(fn, delay) { + var id = counter++, + timer = new java.util.Timer(); + + timeoutIds[id] = [ + new JavaAdapter(java.util.TimerTask,{run: function(){fn(); timer.purge(); timer.cancel();}}), + timer + ]; + + timer.schedule(timeoutIds[id][0], delay); + return id; + } + + global.clearTimeout = function(id) { + if (typeof timeoutIds[id] !== 'undefined') { + timeoutIds[id][0].cancel(); + timeoutIds[id][1].purge(); + timeoutIds[id][1].cancel(); + delete timeoutIds[id]; + } + } + })(); + +})(arguments); \ No newline at end of file diff --git a/node_modules/.bin/nodeunit b/node_modules/.bin/nodeunit new file mode 120000 index 00000000..f31cdbe5 --- /dev/null +++ b/node_modules/.bin/nodeunit @@ -0,0 +1 @@ +../nodeunit/bin/nodeunit \ No newline at end of file diff --git a/node_modules/jsdoc/argparser.js b/node_modules/jsdoc/argparser.js new file mode 100644 index 00000000..108df7f2 --- /dev/null +++ b/node_modules/jsdoc/argparser.js @@ -0,0 +1,140 @@ +/** + Parse the command line arguments. + @module jsdoc/argparser + @author Michael Mathews + @license Apache License 2.0 - See file 'LICENSE.md' in this project. + */ +(function() { + + /** + Create an instance of the parser. + @classdesc A parser to interpret the key value pairs entered on the command + line. + @constructor + */ + exports.ArgParser = function() { + this._options = []; + } + + exports.ArgParser.prototype._getOptionByShortName = function(name) { + for (var i = this._options.length; i--;) { + if (this._options[i].shortName === name) { return this._options[i]; } + } + return null; + } + + exports.ArgParser.prototype._getOptionByLongName = function(name) { + for (var i = this._options.length; i--;) { + if (this._options[i].longName === name) { return this._options[i]; } + } + return null; + } + + /** + * Provide information about a legal option. + * @param {character} shortName The short name of the option, entered like: -T. + * @param {string} longName The equivalent long name of the option, entered like: --test. + * @param {boolean} hasValue Does this option require a value? Like: -t templatename + * @param {string} helpText + * @example + * myParser.addOption('t', 'template', true, 'The path to the template.'); + * myParser.addOption('h', 'help', false, 'Show the help message.'); + */ + exports.ArgParser.prototype.addOption = function(shortName, longName, hasValue, helpText) { + this._options.push({shortName: shortName, longName: longName, hasValue: hasValue, helpText: helpText}); + }; + + /** + Generate a summary of all the options with corresponding help text. + @returns {string} + */ + exports.ArgParser.prototype.help = function() { + var help = 'OPTIONS:\n', + option; + + for (var i = 0, leni = this._options.length; i < leni; i++) { + option = this._options[i]; + + if (option.shortName) { + help += '-' + option.shortName + (option.longName? ' or ' : ''); + } + + if (option.longName) { + help += '--' + option.longName; + } + + if (option.hasValue) { + help += ' '; + } + + help += ' ' + option.helpText + '\n'; + } + + return help; + }; + + /** + Get the options. + @param {Array.} args An array, like ['-x', 'hello'] + @param {Object} [defaults={}] An optional collection of default values. + @returns {Object} The keys will be the longNames, or the shortName if + no longName is defined for that option. The values will be the values + provided, or `true` if the option accepts no value. + */ + exports.ArgParser.prototype.parse = function(args, defaults) { + var result = defaults || {}; + + result._ = []; + + for (var i = 0, leni = args.length; i < leni; i++) { + var arg = '' + args[i], + next = (i < leni-1)? '' + args[i+1] : null, + option, + shortName, + longName, + name, + value = null; + + // like -t + if (arg.charAt(0) === '-') { + + // like: --template + if (arg.charAt(1) === '-') { + name = longName = arg.slice(2); + option = this._getOptionByLongName(longName); + } + else { + name = shortName = arg.slice(1); + option = this._getOptionByShortName(shortName); + } + + if (option === null) { + throw new Error( 'Unknown command line option found: ' + name ); + } + + if (option.hasValue) { + value = next; + i++; + + if (value === null || value.charAt(0) === '-') { + throw new Error( 'Command line option requires a value: ' + name ); + } + } + else { + value = true; + } + + if (option.longName && shortName) { + name = option.longName; + } + + result[name] = value; + } + else { + result._.push(arg); + } + } + + return result; + } +})(); \ No newline at end of file diff --git a/node_modules/jsdoc/doclet.js b/node_modules/jsdoc/doclet.js new file mode 100644 index 00000000..13a21fbb --- /dev/null +++ b/node_modules/jsdoc/doclet.js @@ -0,0 +1,161 @@ +(function() { + var plugin = require('jsdoc/plugin'); + + exports.Doclet = Doclet; + function Doclet(jsdoc, meta) { + if (jsdoc !== '') { + this.tags = this.parseTags(jsdoc); + } + else { + this.tags = []; + } + + plugin.manager.run('doclet', [this]); + } + + Doclet.prototype.parseTags = function(commentSrc) { + // tags have [title, type, pname, text] + + commentSrc = fixDescription( trim(commentSrc) ); + this.src = commentSrc; + var tags = splitTags(commentSrc), + tag; + + for (var i = 0, len = tags.length; i < len; i++) { + tag = tags[i]; + if ( dict.hasOwnProperty(tag.title) ) { + var def = dict[tag.title]; + if (typeof def.onTag === 'function') { + def.onTag(tag, this); + } + } + } + + return tags; + } + + var dict = {}; + dict.name = { + has: ['value'], + title: 'name', + onTag: function(tag, doc) { + tag.text = trim(tag.text); + if (tag.text) doc.name = tag.text; + } + } + + dict.description = { + has: ['value'], + title: 'description', + onTag: function(tag, doc) { + tag.text = trim(tag.text); + doc.description = tag.text; + } + } + dict.desc = dict.description; + + dict['var'] = { + has: ['value'], + title: 'var', + onTag: function(tag, doc) { + doc.kind = 'var'; + dict.name.onTag(tag, doc); // trimmed here + } + }; + + dict['example'] = { + has: ['value'], + title: 'example', + onTag: function(tag, doc) { + // do not trim, whitespace matters in examples + } + }; + + dict['type'] = { + has: ['value'], + title: 'type', + onTag: function(tag, doc) { + tag.text = trim(tag.text); + if ( /\{(.+?)\}/.test(tag.text) ) { + tag.text = trim(RegExp.$1); + } + } + }; + + function trim(text, newlines) { + if (!text) { return ''; } + + if (newlines) { + return text.replace(/^[\n\r\f]+|[\n\r\f]+$/g, ''); + } + else { + return text.replace(/^\s+|\s+$/g, ''); + } + } + + /** + Given the raw source of a jsdoc comment, splits it up into individual tags. + @returns An array of tags, like: [{title, text}], where the original src + would be like: "@title text" + */ + function parseParamText(tagSrc) { + var pname, pdesc, poptional, pdefault; + + // like: pname, pname pdesc, or name - pdesc + tagSrc.match(/^(\[[^\]]+\]|\S+)((?:\s*\-\s*|\s+)(\S[\s\S]*))?$/); + pname = RegExp.$1; + pdesc = RegExp.$3; + + if ( /^\[\s*(.+?)\s*\]$/.test(pname) ) { + pname = RegExp.$1; + poptional = true; + + if ( /^(.+?)\s*=\s*(.+)$/.test(pname) ) { + pname = RegExp.$1; + pdefault = RegExp.$2; + } + } + return [pname, pdesc, poptional, pdefault]; + } + + function fixDescription(docletSrc) { + if (docletSrc && !/^\s*@/.test(docletSrc)) { + docletSrc = '@description ' + docletSrc; + } + return docletSrc; + } + + /** + Given the raw source of a jsdoc comment, splits it up into individual tags. + @returns An array of tags, like: [{title, text}], where the original src + would be like: "@title text" + */ + function splitTags(docletSrc) { + var tagSrcs = []; + + // split out the basic tags, keep surrounding whitespace + // like: @tagTitle tagBody + docletSrc + .replace(/^(\s*)@(\S)/gm, '$1\\@$2') // replace splitter ats with an arbitrary sequence + .split('\\@') // then split on that arbitrary sequence + .forEach(function($) { + if ($) { + var parsedTag = $.match(/^(\S+)(:?\s+(\S[\s\S]*))?/); + + if (parsedTag) { + var tagTitle = parsedTag[1], + tagText = parsedTag[2]; + + if (tagTitle) { + tagSrcs.push({ + title: tagTitle.toLowerCase(), + text: tagText || '' + }); + } + } + } + }); + + return tagSrcs; + } +})(); \ No newline at end of file diff --git a/node_modules/jsdoc/options.js b/node_modules/jsdoc/options.js new file mode 100644 index 00000000..63f3701a --- /dev/null +++ b/node_modules/jsdoc/options.js @@ -0,0 +1,71 @@ +/** + @module jsdoc/options + @requires jsdoc/argparser + @author Michael Mathews + @license Apache License 2.0 - See file 'LICENSE.md' in this project. + */ +(function() { + var argv = require('jsdoc/argparser'); + + var argParser = new argv.ArgParser(), + ourOptions, + defaults = { + template: 'default', + destination: './out/' + }; + + argParser.addOption('t', 'template', true, 'The name of the template to use. Default: the "default" template'); + argParser.addOption('c', 'configure', true, 'The path to the configuration file. Default: jsdoc basedir + conf.json'); + argParser.addOption('e', 'encoding', true, 'Assume this encoding when reading all source files. Default: your system default encoding'); + argParser.addOption('d', 'destination', true, 'The path to the output folder. Use "console" to dump data to the console. Default: console'); + argParser.addOption('V', 'validate', false, 'Validate the results produced by parsing the source code.'); + argParser.addOption('r', 'recurse', false, 'Recurse into subdirectories when scanning for source code files.'); + argParser.addOption('h', 'help', false, 'Print this message and quit.'); + argParser.addOption('X', 'expel', false, 'Dump all found doclet internals to console and quit.'); + argParser.addOption('q', 'query', true, 'Provide a querystring to define custom variable names/values to add to the options hash.'); + + +// TODO [-R, recurseonly] = a number representing the depth to recurse +// TODO [-f, filter] = a regex to filter on <-- this can be better defined in the configs? + + /** + Set the options for this app. + @throws {Error} Illegal arguments will throw errors. + @param {string|String[]} args The command line arguments for this app. + */ + exports.parse = function(args) { + args = args || []; + + if (typeof args === 'string' || args.constructor === String) { + args = (''+args).split(/\s+/g); + } + + ourOptions = argParser.parse(args, defaults); + + return ourOptions; + } + + /** + Display help message for options. + */ + exports.help = function() { + return argParser.help(); + } + + /** + Get a named option. + @param {string} name The name of the option. + @return {string} The value associated with the given name. + *//** + Get all the options for this app. + @return {Object} A collection of key/values representing all the options. + */ + exports.get = function(name) { + if (typeof name === 'undefined') { + return ourOptions; + } + else { + return ourOptions[name]; + } + } +})(); \ No newline at end of file diff --git a/node_modules/jsdoc/parser.js b/node_modules/jsdoc/parser.js new file mode 100644 index 00000000..b6dc00a1 --- /dev/null +++ b/node_modules/jsdoc/parser.js @@ -0,0 +1,136 @@ +(function() { + + var Narcissus = require('narcissus').Narcissus, + Doclet = require('jsdoc/doclet').Doclet; + + + // handle orphaned doclets, associated with no code token + Narcissus.parser.Tokenizer.prototype.onJsDoc = function(doclet, meta) { + handle.JSDOC(doclet); + } + + var path, + symbols = 'wtf'; + + exports.parse = function(src) { + symbols = []; + + // may call handle.JSDOC + var ast = Narcissus.parser.parse(src, '', 1); +//console.log(String(ast)); + path = []; + + walk(ast.children); + + return symbols; + } + + function defined(o) { + return typeof o !== 'undefined'; + } + + function typeToName(type) { + var name; + if (name = typeToName.types[type]) { + return name; + } + return type; + } + typeToName.types = ['END', 'NEWLINE', 'SEMICOLON', 'COMMA', 'ASSIGN', 'HOOK', 'COLON', 'CONDITIONAL', 'OR', 'AND', 'BITWISE_OR', 'BITWISE_XOR', 'BITWISE_AND', 'EQ', 'NE', 'STRICT_EQ', 'STRICT_NE', 'LT', 'LE', 'GE', 'GT', 'LSH', 'RSH', 'URSH', 'PLUS', 'MINUS', 'MUL', 'DIV', 'MOD', 'NOT', 'BITWISE_NOT', 'UNARY_PLUS', 'UNARY_MINUS', 'INCREMENT', 'DECREMENT', 'DOT', 'LEFT_BRACKET', 'RIGHT_BRACKET', 'LEFT_CURLY', 'RIGHT_CURLY', 'LEFT_PAREN', 'RIGHT_PAREN', 'SCRIPT', 'BLOCK', 'LABEL', 'FOR_IN', 'CALL', 'NEW_WITH_ARGS', 'INDEX', 'ARRAY_INIT', 'OBJECT_INIT', 'PROPERTY_INIT', 'GETTER', 'SETTER', 'GROUP', 'LIST', 'LET_BLOCK', 'ARRAY_COMP', 'GENERATOR', 'COMP_TAIL', 'IDENTIFIER', 'NUMBER', 'STRING', 'REGEXP', 'BREAK', 'CASE', 'CATCH', 'CONST', 'CONTINUE', 'DEBUGGER', 'DEFAULT', 'DELETE', 'DO', 'ELSE', 'EXPORT', 'FALSE', 'FINALLY', 'FOR', 'FUNCTION', 'IF', 'IMPORT', 'IN', 'INSTANCEOF', 'LET', 'MODULE', 'NEW', 'NULL', 'RETURN', 'SWITCH', 'THIS', 'THROW', 'TRUE', 'TRY', 'TYPEOF', 'VAR', 'VOID', 'YIELD', 'WHILE', 'WITH']; + + var handle = { + JSDOC: function(jsdoc) { + //console.log( '>>> jsdoc "'+jsdoc+'"' ); + symbols.push({longname: null, jsdoc: new Doclet(jsdoc)}); + }, + VAR: function(node) { + var child = null, + varDoc = defined(node.jsdoc)? node.jsdoc : ''; + + while ( child = node.children.shift() ) { + if (varDoc) { + child.jsdoc = varDoc; + varDoc = null; + } + + var namePath = path.join('') + (path.length?'~':'') + child.name; + symbols.push({longname: namePath, jsdoc: defined(child.jsdoc)? new Doclet(child.jsdoc) : new Doclet('')}); + //console.log( '>>> variable '+namePath+(defined(child.jsdoc)? ' "'+child.jsdoc+'"' : '') ); + var children = walkable(child); + if (children) { walk(children); } + } + }, + FUNCTION: function(node) { + var namePath = path.join('') + (path.length?'~':'') + node.name, + jsdoc = defined(node.jsdoc)? node.jsdoc : ''; + + symbols.push({longname: namePath, jsdoc: new Doclet(jsdoc)}); + //console.log( '>>> function '+namePath+(defined(node.jsdoc)? ' "'+node.jsdoc+'"' : '') ); + path.push((path.length?'~':'')+node.name); + walk(node.body.children); + path.pop(); + }, + OBJECT_INIT: function(node) { + console.log( '>>> TODO object literal '+node.name+' '+node.jsdoc); + + } + + }; + + function walk(ast) { +//console.log('walk('+ast.length+')'); + var node = null, + nodeType = -1; + + while (node = ast.shift()) { + nodeType = typeToName(node.type); +//console.log('~>>>> nodeType: '+nodeType+' '+node.name); + if (handle.hasOwnProperty(nodeType) && typeof handle[nodeType] === 'function') { + handle[nodeType](node); + } + else if (node.jsdoc) { + handle.JSDOC(node.jsdoc); + } + + var children = walkable(node); + if (children) { walk(children); } + } + } + + function walkable(node) { + //console.log('>>> getting walkables of: '+typeToName(node.type)+' '+node.name); + if ( defined(node.body) && defined(node.body.children) && node.body.children !== null) { + //console.log('- has body/children'); + return node.body.children; + } + if ( defined(node.expression) && node.expression && defined(node.expression.children) && node.expression.children ) { + //console.log('- has expression/children'); + return node.expression.children; + } + // like: foo = function(){} + if ( defined(node.initializer)) { + //console.log('- has initializer'); + if (typeToName(node.initializer.type) === 'FUNCTION') { + //console.log('- has function value'); + path.push('~'+node.name); + return(node.initializer.body.children); + } + else if (typeToName(node.initializer.type) === 'OBJECT_INIT') { + //console.log('- has object value'); + path.push('~'+node.name); + return(node.initializer.children); + } + // like foo = /**doc*/{}; + else if (node.initializer.jsdoc) { + handle.JSDOC(node.initializer.jsdoc); + } + } + if ( defined(node.children) ) { + //console.log('- has children '+node.children.length); + return node.children; + } + //console.log('nothing to walk'); + } + + +})(); \ No newline at end of file diff --git a/node_modules/jsdoc/plugin.js b/node_modules/jsdoc/plugin.js new file mode 100644 index 00000000..2e103b4d --- /dev/null +++ b/node_modules/jsdoc/plugin.js @@ -0,0 +1,28 @@ +if (typeof global.pluginRegistry === 'undefined') { + global.pluginRegistry = {}; +} +registry = global.pluginRegistry; + +exports.manager = manager = { + on: function(name, callback) { +//console.log('on '+name); + if (!registry.hasOwnProperty(name)) { + registry[name] = []; + } + registry[name].push(callback); +//console.log('on registry '+registry.toSource()); + }, + run: function(name, args) { +//console.log('run '+name); +//consoleconsole.log('run registry '+registry.toSource()); + if (registry.hasOwnProperty(name)) { + var callbacks = registry[name]; +//console.log('callbacks '+callbacks.length); + for (var i = 0, len = callbacks.length; i < len; i++) { + callbacks[i].apply(manager, args); + } + } + } + +} + diff --git a/node_modules/jsdoc/util/dumper.js b/node_modules/jsdoc/util/dumper.js new file mode 100644 index 00000000..b7a094d9 --- /dev/null +++ b/node_modules/jsdoc/util/dumper.js @@ -0,0 +1,158 @@ +/** + Recursively print out all names and values in a data structure. + @module common/dumper + @author Michael Mathews + @license Apache License 2.0 - See file 'LICENSE.md' in this project. + */ +(function() { + /** + @param {any} object + */ + exports.dump = function(object) { + indentBy = 0; + output = ''; + + walk(object); + outdent(false); + return output; + } + + const INDENTATION = ' '; // 4 spaces + var indentBy, + output; + + function pad(depth) { + var padding = ''; + while (depth--) { + padding += INDENTATION; + } + return padding; + } + + /** + @param {string} openingBrace - The opening brace to add, like "{". + @private + @inner + @memberof module:common/dumper + */ + function indent(openingBrace) { + indentBy++; + if (openingBrace) output += openingBrace + '\n'; + } + + /** + @param {string|boolean} closingBrace - The closing brace to add, like "}" or if boolean + `false` no closing brace or trailing newline. + @private + @inner + @memberof module:common/dumper + */ + function outdent(closingBrace) { + indentBy--; + output = output.replace(/,\n$/, '\n'); // trim trailing comma + if (closingBrace === false) { output = output.replace(/\n$/, ''); } + else if (closingBrace) output += pad(indentBy) + closingBrace + ',\n'; + } + + var seen = []; + seen.has = function(object) { + for (var i = 0, l = seen.length; i < l; i++) { + if (seen[i] === object) { return true; } + } + return false; + } + + function walk(object) { + var value; + + if ( value = getValue(object) ) { + output += value + ',\n'; + } + else if ( isUnwalkable(object) ) { + output += ',\n' + } + else if ( isRegExp(object) ) { + output += ',\n' + } + else if ( isDate(object) ) { + output += ',\n' + } + else if ( isFunction(object) ) { + output += ',\n'; + } + else if ( isArray(object) ) { + if ( seen.has(object) ) { + output += ',\n'; + return; + } + else { + seen.push(object); + } + + indent('['); + for (var i = 0, leni = object.length; i < leni; i++) { + output += pad(indentBy); // + i + ': '; + walk( object[i] ); + } + outdent(']'); + } + else if ( isObject(object) ) { + if ( seen.has(object) ) { + output += ',\n'; + return; + } + else { + seen.push(object); + } + + indent('{'); + for (var p in object) { + if ( object.hasOwnProperty(p) ) { + output += pad(indentBy) + stringify(p) + ': '; + walk( object[p] ); + } + } + outdent('}'); + } + } + + function getValue(o) { // see: https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/typeof + if (o === null) { return 'null'; } + if ( /^(string|boolean|number|undefined)$/.test(typeof o) ) { + return ''+stringify(o); + } + } + + function stringify(o) { + return JSON.stringify(o); + } + + function isUnwalkable(o) { // some objects are unwalkable, like Java native objects + return (typeof o === 'object' && typeof o.constructor === 'undefined'); + } + + function isArray(o) { + return o && (o instanceof Array) || o.constructor === Array; + } + + function isRegExp(o) { + return (o instanceof RegExp) || + (typeof o.constructor !== 'undefined' && o.constructor.name === 'RegExp'); + } + + function isDate(o) { + return o && (o instanceof Date) || + (typeof o.constructor !== 'undefined' && o.constructor.name === 'Date'); + } + + function isFunction(o) { + return o && (typeof o === 'function' || o instanceof Function);// || + //(typeof o.constructor !== 'undefined' && (o.constructor||{}).name === 'Function'); + } + + function isObject(o) { + return o && o instanceof Object || + (typeof o.constructor !== 'undefined' && o.constructor.name === 'Object'); + } + +})(); \ No newline at end of file diff --git a/node_modules/jsecma5.js b/node_modules/jsecma5.js new file mode 100644 index 00000000..d5946601 --- /dev/null +++ b/node_modules/jsecma5.js @@ -0,0 +1,33 @@ +// ECMAScript3 versions of ECMAScript5 constructs used in Narcissus parser +// All properties will be writable, configurable and enumerable, no matter +// the descriptor. Descriptor get/set is also ignored. + +(function() { + if (Object.defineProperty === undefined) { + Object.defineProperty = function(obj, prop, descriptor) { + obj[prop] = descriptor.value; + }; + } + + if (Object.defineProperties === undefined) { + Object.defineProperties = function(obj, props) { + for (var prop in props) { + if (props.hasOwnProperty(prop)) { + Object.defineProperty(obj, prop, props[prop]); + } + } + }; + } + + if (Object.create === undefined) { + Object.create = function(obj, props) { + function ctor() {} + ctor.prototype = obj; + var o = new ctor(); + if (props !== undefined) { + Object.defineProperties(o, props); + } + return o; + }; + } +})(); diff --git a/node_modules/jsmods.js b/node_modules/jsmods.js new file mode 100644 index 00000000..0a149fb8 --- /dev/null +++ b/node_modules/jsmods.js @@ -0,0 +1,5 @@ +// module keyword is removed so that it parses like any identifier +delete Narcissus.definitions.tokens.module; +delete Narcissus.definitions.keywords.module; +delete Narcissus.definitions.tokenIds.module; +/* global */ tkn = Narcissus.definitions.tokenIds; diff --git a/node_modules/markdown/.gitignore b/node_modules/markdown/.gitignore new file mode 100644 index 00000000..a01ee289 --- /dev/null +++ b/node_modules/markdown/.gitignore @@ -0,0 +1 @@ +.*.swp diff --git a/node_modules/markdown/README.markdown b/node_modules/markdown/README.markdown new file mode 100644 index 00000000..30afcad7 --- /dev/null +++ b/node_modules/markdown/README.markdown @@ -0,0 +1,68 @@ +markdown-js +=========== + +Yet another markdown parser, this time for JavaScript. There's a few +options that precede this project but they all treat markdown to HTML +conversion as a single step process. You pass markdown in and get HTML +out, end of story. We had some pretty particular views on how the +process should actually look, which include: + + * producing well-formed HTML. This means that em and strong nesting is + important, as is the ability to output as both HTML and XHTML + + * having an intermediate representation to allow processing of parsed + data (we in fact have two, both [JsonML]: a markdown tree and an + HTML tree) + + * being easily extensible to add new dialects without having to + rewrite the entire parsing mechanics + + * having a good test suite. The only test suites we could find tested + massive blocks of input, and passing depended on outputting the HTML + with exactly the same whitespace as the original implementation + +[JsonML]: http://jsonml.org/ "JSON Markup Language" + +## Usage + +The simple way to use it with CommonJS is: + + var input = "# Heading\n\nParagraph"; + var output = require( "markdown" ).toHTML( input ); + print( output ); + +If you want more control check out the documentation in +[lib/markdown.js] which details all the methods and parameters +available (including examples!). One day we'll get the docs generated +and hosted somewhere for nicer browsing. + +We're yet to try it out in a browser, though it's high up on our list of +things to sort out for this project. + +[lib/markdown.js]: http://github.com/evilstreak/markdown-js/blob/master/lib/markdown.js + +## Intermediate Representation + +Internally the process to convert a chunk of markdown into a chunk of +HTML has three steps: + + 1. Parse the markdown into a JsonML tree. Any references found in the + parsing are stored in the attribute hash of the root node under the + key `references`. + + 2. Convert the markdown tree into an HTML tree. Rename any nodes that + need it (`bulletlist` to `ul` for example) and lookup any references + used by links or images. Remove the references attribute once done. + + 3. Stringify the HTML tree being careful not to wreck whitespace where + whitespace is important (surrounding inline elements for example). + +Each step of this process can be called individually if you need to do +some processing or modification of the data at an intermediate stage. +For example, you may want to grab a list of all URLs linked to in the +document before rendering it to HTML which you could do by recursing +through the HTML tree looking for `a` nodes. + +## License + +Released under the MIT license. diff --git a/node_modules/markdown/lib/index.js b/node_modules/markdown/lib/index.js new file mode 100644 index 00000000..8bb08734 --- /dev/null +++ b/node_modules/markdown/lib/index.js @@ -0,0 +1,3 @@ +// super simple module for the most common nodejs use case. +exports.markdown = require("./markdown"); +exports.parse = exports.markdown.toHTML; diff --git a/node_modules/markdown/lib/markdown.js b/node_modules/markdown/lib/markdown.js new file mode 100644 index 00000000..1686db4c --- /dev/null +++ b/node_modules/markdown/lib/markdown.js @@ -0,0 +1,1452 @@ +// Released under MIT license +// Copyright (c) 2009-2010 Dominic Baggott +// Copyright (c) 2009-2010 Ash Berlin + +(function( expose ) { + +/** + * class Markdown + * + * Markdown processing in Javascript done right. We have very particular views + * on what constitutes 'right' which include: + * + * - produces well-formed HTML (this means that em and strong nesting is + * important) + * + * - has an intermediate representation to allow processing of parsed data (We + * in fact have two, both as [JsonML]: a markdown tree and an HTML tree). + * + * - is easily extensible to add new dialects without having to rewrite the + * entire parsing mechanics + * + * - has a good test suite + * + * This implementation fulfills all of these (except that the test suite could + * do with expanding to automatically run all the fixtures from other Markdown + * implementations.) + * + * ##### Intermediate Representation + * + * *TODO* Talk about this :) Its JsonML, but document the node names we use. + * + * [JsonML]: http://jsonml.org/ "JSON Markup Language" + **/ +var Markdown = expose.Markdown = function Markdown(dialect) { + switch (typeof dialect) { + case "undefined": + this.dialect = Markdown.dialects.Gruber; + break; + case "object": + this.dialect = dialect; + break; + default: + if (dialect in Markdown.dialects) { + this.dialect = Markdown.dialects[dialect]; + } + else { + throw new Error("Unknown Markdown dialect '" + String(dialect) + "'"); + } + break; + } + this.em_state = []; + this.strong_state = []; + this.debug_indent = ""; +} + +/** + * parse( markdown, [dialect] ) -> JsonML + * - markdown (String): markdown string to parse + * - dialect (String | Dialect): the dialect to use, defaults to gruber + * + * Parse `markdown` and return a markdown document as a Markdown.JsonML tree. + **/ +expose.parse = function( source, dialect ) { + // dialect will default if undefined + var md = new Markdown( dialect ); + return md.toTree( source ); +} + +/** + * toHTML( markdown, [dialect] ) -> String + * toHTML( md_tree ) -> String + * - markdown (String): markdown string to parse + * - md_tree (Markdown.JsonML): parsed markdown tree + * + * Take markdown (either as a string or as a JsonML tree) and run it through + * [[toHTMLTree]] then turn it into a well-formated HTML fragment. + **/ +expose.toHTML = function toHTML( source , dialect ) { + var input = expose.toHTMLTree( source , dialect ); + + return expose.renderJsonML( input ); +} + +/** + * toHTMLTree( markdown, [dialect] ) -> JsonML + * toHTMLTree( md_tree ) -> JsonML + * - markdown (String): markdown string to parse + * - dialect (String | Dialect): the dialect to use, defaults to gruber + * - md_tree (Markdown.JsonML): parsed markdown tree + * + * Turn markdown into HTML, represented as a JsonML tree. If a string is given + * to this function, it is first parsed into a markdown tree by calling + * [[parse]]. + **/ +expose.toHTMLTree = function toHTMLTree( input, dialect ) { + // convert string input to an MD tree + if ( typeof input ==="string" ) input = this.parse( input, dialect ); + + // Now convert the MD tree to an HTML tree + + // remove references from the tree + var attrs = extract_attr( input ), + refs = {}; + + if ( attrs && attrs.references ) { + refs = attrs.references; + } + + var html = convert_tree_to_html( input, refs ); + merge_text_nodes( html ); + return html; +} + +var mk_block = Markdown.mk_block = function(block, trail, line) { + // Be helpful for default case in tests. + if ( arguments.length == 1 ) trail = "\n\n"; + + var s = new String(block); + s.trailing = trail; + // To make it clear its not just a string + s.toSource = function() { + return "Markdown.mk_block( " + + uneval(block) + + ", " + + uneval(trail) + + ", " + + uneval(line) + + " )" + } + + if (line != undefined) + s.lineNumber = line; + + return s; +} + +function count_lines( str ) { + var n = 0, i = -1;; + while ( ( i = str.indexOf('\n', i+1) ) != -1) n++; + return n; +} + +// Internal - split source into rough blocks +Markdown.prototype.split_blocks = function splitBlocks( input, startLine ) { + // [\s\S] matches _anything_ (newline or space) + var re = /([\s\S]+?)($|\n(?:\s*\n|$)+)/g, + blocks = [], + m; + + var line_no = 1; + + if ( ( m = (/^(\s*\n)/)(input) ) != null ) { + // skip (but count) leading blank lines + line_no += count_lines( m[0] ); + re.lastIndex = m[0].length; + } + + while ( ( m = re(input) ) != null ) { + blocks.push( mk_block( m[1], m[2], line_no ) ); + line_no += count_lines( m[0] ); + } + + return blocks; +} + +/** + * Markdown#processBlock( block, next ) -> undefined | [ JsonML, ... ] + * - block (String): the block to process + * - next (Array): the following blocks + * + * Process `block` and return an array of JsonML nodes representing `block`. + * + * It does this by asking each block level function in the dialect to process + * the block until one can. Succesful handling is indicated by returning an + * array (with zero or more JsonML nodes), failure by a false value. + * + * Blocks handlers are responsible for calling [[Markdown#processInline]] + * themselves as appropriate. + * + * If the blocks were split incorrectly or adjacent blocks need collapsing you + * can adjust `next` in place using shift/splice etc. + * + * If any of this default behaviour is not right for the dialect, you can + * define a `__call__` method on the dialect that will get invoked to handle + * the block processing. + */ +Markdown.prototype.processBlock = function processBlock( block, next ) { + var cbs = this.dialect.block, + ord = cbs.__order__; + + if ( "__call__" in cbs ) { + return cbs.__call__.call(this, block, next); + } + + for ( var i = 0; i < ord.length; i++ ) { + //D:this.debug( "Testing", ord[i] ); + var res = cbs[ ord[i] ].call( this, block, next ); + if ( res ) { + //D:this.debug(" matched"); + if ( !res instanceof Array || ( res.length > 0 && !( res[0] instanceof Array ) ) ) + this.debug(ord[i], "didn't return a proper array"); + //D:this.debug( "" ); + return res; + } + } + + // Uhoh! no match! Should we throw an error? + return []; +} + +Markdown.prototype.processInline = function processInline( block ) { + return this.dialect.inline.__call__.call( this, String( block ) ); +} + +/** + * Markdown#toTree( source ) -> JsonML + * - source (String): markdown source to parse + * + * Parse `source` into a JsonML tree representing the markdown document. + **/ +// custom_tree means set this.tree to `custom_tree` and restore old value on return +Markdown.prototype.toTree = function toTree( source, custom_root ) { + var blocks = source instanceof Array + ? source + : this.split_blocks( source ); + + // Make tree a member variable so its easier to mess with in extensions + var old_tree = this.tree; + try { + this.tree = custom_root || this.tree || [ "markdown" ]; + + blocks: + while ( blocks.length ) { + var b = this.processBlock( blocks.shift(), blocks ); + + // Reference blocks and the like won't return any content + if ( !b.length ) continue blocks; + + this.tree.push.apply( this.tree, b ); + } + return this.tree; + } + finally { + if ( custom_root ) + this.tree = old_tree; + } + +} + +// Noop by default +Markdown.prototype.debug = function () { + var args = Array.prototype.slice.call( arguments); + args.unshift(this.debug_indent); + print.apply( print, args ); +} + +Markdown.prototype.loop_re_over_block = function( re, block, cb ) { + // Dont use /g regexps with this + var m, + b = block.valueOf(); + + while ( b.length && (m = re(b) ) != null) { + b = b.substr( m[0].length ); + cb.call(this, m); + } + return b; +} + +/** + * Markdown.dialects + * + * Namespace of built-in dialects. + **/ +Markdown.dialects = {}; + +/** + * Markdown.dialects.Gruber + * + * The default dialect that follows the rules set out by John Gruber's + * markdown.pl as closely as possible. Well actually we follow the behaviour of + * that script which in some places is not exactly what the syntax web page + * says. + **/ +Markdown.dialects.Gruber = { + block: { + atxHeader: function atxHeader( block, next ) { + var m = block.match( /^(#{1,6})\s*(.*?)\s*#*\s*(?:\n|$)/ ); + + if ( !m ) return undefined; + + var header = [ "header", { level: m[ 1 ].length }, m[ 2 ] ]; + + if ( m[0].length < block.length ) + next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) ); + + return [ header ]; + }, + + setextHeader: function setextHeader( block, next ) { + var m = block.match( /^(.*)\n([-=])\2\2+(?:\n|$)/ ); + + if ( !m ) return undefined; + + var level = ( m[ 2 ] === "=" ) ? 1 : 2; + var header = [ "header", { level : level }, m[ 1 ] ]; + + if ( m[0].length < block.length ) + next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) ); + + return [ header ]; + }, + + code: function code( block, next ) { + // | Foo + // |bar + // should be a code block followed by a paragraph. Fun + // + // There might also be adjacent code block to merge. + + var ret = [], + re = /^(?: {0,3}\t| {4})(.*)\n?/, + lines; + + // 4 spaces + content + var m = block.match( re ); + + if ( !m ) return undefined; + + block_search: + do { + // Now pull out the rest of the lines + var b = this.loop_re_over_block( + re, block.valueOf(), function( m ) { ret.push( m[1] ) } ); + + if (b.length) { + // Case alluded to in first comment. push it back on as a new block + next.unshift( mk_block(b, block.trailing) ); + break block_search; + } + else if (next.length) { + // Check the next block - it might be code too + var m = next[0].match( re ); + + if ( !m ) break block_search; + + // Pull how how many blanks lines follow - minus two to account for .join + ret.push ( block.trailing.replace(/[^\n]/g, '').substring(2) ); + + block = next.shift(); + } + else + break block_search; + } while (true); + + return [ [ "code_block", ret.join("\n") ] ]; + }, + + horizRule: function horizRule( block, next ) { + // this needs to find any hr in the block to handle abutting blocks + var m = block.match( /^(?:([\s\S]*?)\n)?[ \t]*([-_*])(?:[ \t]*\2){2,}[ \t]*(?:\n([\s\S]*))?$/ ); + + if ( !m ) { + return undefined; + } + + var jsonml = [ [ "hr" ] ]; + + // if there's a leading abutting block, process it + if ( m[ 1 ] ) { + jsonml.unshift.apply( jsonml, this.processBlock( m[ 1 ], [] ) ); + } + + // if there's a trailing abutting block, stick it into next + if ( m[ 3 ] ) { + next.unshift( mk_block( m[ 3 ] ) ); + } + + return jsonml; + }, + + // There are two types of lists. Tight and loose. Tight lists have no whitespace + // between the items (and result in text just in the
  • ) and loose lists, + // which have an empty line between list items, resulting in (one or more) + // paragraphs inside the
  • . + // + // There are all sorts weird edge cases about the original markdown.pl's + // handling of lists: + // + // * Nested lists are supposed to be indented by four chars per level. But + // if they aren't, you can get a nested list by indenting by less than + // four so long as the indent doesn't match an indent of an existing list + // item in the 'nest stack'. + // + // * The type of the list (bullet or number) is controlled just by the + // first item at the indent. Subsequent changes are ignored unless they + // are for nested lists + // + lists: (function( ) { + // Use a closure to hide a few variables. + var any_list = "[*+-]|\\d\\.", + bullet_list = /[*+-]/, + number_list = /\d+\./, + // Capture leading indent as it matters for determining nested lists. + is_list_re = new RegExp( "^( {0,3})(" + any_list + ")[ \t]+" ), + indent_re = "(?: {0,3}\\t| {4})"; + + // TODO: Cache this regexp for certain depths. + // Create a regexp suitable for matching an li for a given stack depth + function regex_for_depth( depth ) { + + return new RegExp( + // m[1] = indent, m[2] = list_type + "(?:^(" + indent_re + "{0," + depth + "} {0,3})(" + any_list + ")\\s+)|" + + // m[3] = cont + "(^" + indent_re + "{0," + (depth-1) + "}[ ]{0,4})" + ); + } + function expand_tab( input ) { + return input.replace( / {0,3}\t/g, " " ); + } + + // Add inline content `inline` to `li`. inline comes from processInline + // so is an array of content + function add(li, loose, inline, nl) { + if (loose) { + li.push( [ "para" ].concat(inline) ); + return; + } + // Hmmm, should this be any block level element or just paras? + var add_to = li[li.length -1] instanceof Array && li[li.length - 1][0] == "para" + ? li[li.length -1] + : li; + + // If there is already some content in this list, add the new line in + if (nl && li.length > 1) inline.unshift(nl); + + for (var i=0; i < inline.length; i++) { + var what = inline[i], + is_str = typeof what == "string"; + if (is_str && add_to.length > 1 && typeof add_to[add_to.length-1] == "string" ) + { + add_to[ add_to.length-1 ] += what; + } + else { + add_to.push( what ); + } + } + } + + // contained means have an indent greater than the current one. On + // *every* line in the block + function get_contained_blocks( depth, blocks ) { + + var re = new RegExp( "^(" + indent_re + "{" + depth + "}.*?\\n?)*$" ), + replace = new RegExp("^" + indent_re + "{" + depth + "}", "gm"), + ret = []; + + while ( blocks.length > 0 ) { + if ( re( blocks[0] ) ) { + var b = blocks.shift(), + // Now remove that indent + x = b.replace( replace, ""); + + ret.push( mk_block( x, b.trailing, b.lineNumber ) ); + } + break; + } + return ret; + } + + // passed to stack.forEach to turn list items up the stack into paras + function paragraphify(s, i, stack) { + var list = s.list; + var last_li = list[list.length-1]; + + if (last_li[1] instanceof Array && last_li[1][0] == "para") { + return; + } + if (i+1 == stack.length) { + // Last stack frame + // Keep the same array, but replace the contents + last_li.push( ["para"].concat( last_li.splice(1) ) ); + } + else { + var sublist = last_li.pop(); + last_li.push( ["para"].concat( last_li.splice(1) ), sublist ); + } + } + + // The matcher function + return function( block, next ) { + var m = block.match( is_list_re ); + if ( !m ) return undefined; + + function make_list( m ) { + var list = bullet_list( m[2] ) + ? ["bulletlist"] + : ["numberlist"]; + + stack.push( { list: list, indent: m[1] } ); + return list; + } + + + var stack = [], // Stack of lists for nesting. + list = make_list( m ), + last_li, + loose = false, + ret = [ stack[0].list ]; + + // Loop to search over block looking for inner block elements and loose lists + loose_search: + while( true ) { + // Split into lines preserving new lines at end of line + var lines = block.split( /(?=\n)/ ); + + // We have to grab all lines for a li and call processInline on them + // once as there are some inline things that can span lines. + var li_accumulate = ""; + + // Loop over the lines in this block looking for tight lists. + tight_search: + for (var line_no=0; line_no < lines.length; line_no++) { + var nl = "", + l = lines[line_no].replace(/^\n/, function(n) { nl = n; return "" }); + + // TODO: really should cache this + var line_re = regex_for_depth( stack.length ); + + m = l.match( line_re ); + //print( "line:", uneval(l), "\nline match:", uneval(m) ); + + // We have a list item + if ( m[1] !== undefined ) { + // Process the previous list item, if any + if ( li_accumulate.length ) { + add( last_li, loose, this.processInline( li_accumulate ), nl ); + // Loose mode will have been dealt with. Reset it + loose = false; + li_accumulate = ""; + } + + m[1] = expand_tab( m[1] ); + var wanted_depth = Math.floor(m[1].length/4)+1; + //print( "want:", wanted_depth, "stack:", stack.length); + if ( wanted_depth > stack.length ) { + // Deep enough for a nested list outright + //print ( "new nested list" ); + list = make_list( m ); + last_li.push( list ); + last_li = list[1] = [ "listitem" ]; + } + else { + // We aren't deep enough to be strictly a new level. This is + // where Md.pl goes nuts. If the indent matches a level in the + // stack, put it there, else put it one deeper then the + // wanted_depth deserves. + var found = stack.some(function(s, i) { + if ( s.indent != m[1] ) return false; + list = s.list; // Found the level we want + stack.splice(i+1); // Remove the others + //print("found"); + return true; // And stop looping + }); + + if (!found) { + //print("not found. l:", uneval(l)); + wanted_depth++; + if (wanted_depth <= stack.length) { + stack.splice(wanted_depth); + //print("Desired depth now", wanted_depth, "stack:", stack.length); + list = stack[wanted_depth-1].list; + //print("list:", uneval(list) ); + } + else { + //print ("made new stack for messy indent"); + list = make_list(m); + last_li.push(list); + } + } + + //print( uneval(list), "last", list === stack[stack.length-1].list ); + last_li = [ "listitem" ]; + list.push(last_li); + } // end depth of shenegains + nl = ""; + } + + // Add content + if (l.length > m[0].length) { + li_accumulate += nl + l.substr( m[0].length ); + } + } // tight_search + + if ( li_accumulate.length ) { + add( last_li, loose, this.processInline( li_accumulate ), nl ); + // Loose mode will have been dealt with. Reset it + loose = false; + li_accumulate = ""; + } + + // Look at the next block - we might have a loose list. Or an extra + // paragraph for the current li + var contained = get_contained_blocks( stack.length, next ); + + // Deal with code blocks or properly nested lists + if (contained.length > 0) { + // Make sure all listitems up the stack are paragraphs + stack.forEach( paragraphify, this ); + + last_li.push.apply( last_li, this.toTree( contained, [] ) ); + } + + var next_block = next[0] && next[0].valueOf() || ""; + + if ( next_block.match(is_list_re) || next_block.match( /^ / ) ) { + block = next.shift(); + + // Check for an HR following a list: features/lists/hr_abutting + var hr = this.dialect.block.horizRule( block, next ); + + if (hr) { + ret.push.apply(ret, hr); + break; + } + + // Make sure all listitems up the stack are paragraphs + stack.forEach( paragraphify , this ); + + loose = true; + continue loose_search; + } + break; + } // loose_search + + return ret; + } + })(), + + blockquote: function blockquote( block, next ) { + if ( !block.match( /^>/m ) ) + return undefined; + + var jsonml = []; + + // separate out the leading abutting block, if any + if ( block[ 0 ] != ">" ) { + var lines = block.split( /\n/ ), + prev = []; + + // keep shifting lines until you find a crotchet + while ( lines.length && lines[ 0 ][ 0 ] != ">" ) { + prev.push( lines.shift() ); + } + + // reassemble! + block = lines.join( "\n" ); + jsonml.push.apply( jsonml, this.processBlock( prev.join( "\n" ), [] ) ); + } + + // if the next block is also a blockquote merge it in + while ( next.length && next[ 0 ][ 0 ] == ">" ) { + var b = next.shift(); + block += block.trailing + b; + block.trailing = b.trailing; + } + + // Strip off the leading "> " and re-process as a block. + var input = block.replace( /^> ?/gm, '' ), + old_tree = this.tree; + jsonml.push( this.toTree( input, [ "blockquote" ] ) ); + + return jsonml; + }, + + referenceDefn: function referenceDefn( block, next) { + var re = /^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/; + // interesting matches are [ , ref_id, url, , title, title ] + + if ( !block.match(re) ) + return undefined; + + // make an attribute node if it doesn't exist + if ( !extract_attr( this.tree ) ) { + this.tree.splice( 1, 0, {} ); + } + + var attrs = extract_attr( this.tree ); + + // make a references hash if it doesn't exist + if ( attrs.references === undefined ) { + attrs.references = {}; + } + + var b = this.loop_re_over_block(re, block, function( m ) { + + if ( m[2] && m[2][0] == '<' && m[2][m[2].length-1] == '>' ) + m[2] = m[2].substring( 1, m[2].length - 1 ); + + var ref = attrs.references[ m[1].toLowerCase() ] = { + href: m[2] + }; + + if (m[4] !== undefined) + ref.title = m[4]; + else if (m[5] !== undefined) + ref.title = m[5]; + + } ); + + if (b.length) + next.unshift( mk_block( b, block.trailing ) ); + + return []; + }, + + para: function para( block, next ) { + // everything's a para! + return [ ["para"].concat( this.processInline( block ) ) ]; + } + } +} + +Markdown.dialects.Gruber.inline = { + __call__: function inline( text, patterns ) { + // Hmmm - should this function be directly in Md#processInline, or + // conversely, should Md#processBlock be moved into block.__call__ too + var out = [ ], + m, + // Look for the next occurange of a special character/pattern + re = new RegExp( "([\\s\\S]*?)(" + (patterns.source || patterns) + ")", "g" ), + lastIndex = 0; + + //D:var self = this; + //D:self.debug("processInline:", uneval(text) ); + function add(x) { + //D:self.debug(" adding output", uneval(x)); + if (typeof x == "string" && typeof out[out.length-1] == "string") + out[ out.length-1 ] += x; + else + out.push(x); + } + + while ( ( m = re.exec(text) ) != null) { + if ( m[1] ) add( m[1] ); // Some un-interesting text matched + else m[1] = { length: 0 }; // Or there was none, but make m[1].length == 0 + + var res; + if ( m[2] in this.dialect.inline ) { + res = this.dialect.inline[ m[2] ].call( + this, + text.substr( m.index + m[1].length ), m, out ); + } + // Default for now to make dev easier. just slurp special and output it. + res = res || [ m[2].length, m[2] ]; + + var len = res.shift(); + // Update how much input was consumed + re.lastIndex += ( len - m[2].length ); + + // Add children + res.forEach(add); + + lastIndex = re.lastIndex; + } + + // Add last 'boring' chunk + if ( text.length > lastIndex ) + add( text.substr( lastIndex ) ); + + return out; + }, + + "\\": function escaped( text ) { + // [ length of input processed, node/children to add... ] + // Only esacape: \ ` * _ { } [ ] ( ) # * + - . ! + if ( text.match( /^\\[\\`\*_{}\[\]()#\+.!\-]/ ) ) + return [ 2, text[1] ]; + else + // Not an esacpe + return [ 1, "\\" ]; + }, + + "![": function image( text ) { + // ![Alt text](/path/to/img.jpg "Optional title") + // 1 2 3 4 <--- captures + var m = text.match( /^!\[(.*?)\][ \t]*\([ \t]*(\S*)(?:[ \t]+(["'])(.*?)\3)?[ \t]*\)/ ); + + if ( m ) { + if ( m[2] && m[2][0] == '<' && m[2][m[2].length-1] == '>' ) + m[2] = m[2].substring( 1, m[2].length - 1 ); + + m[2] == this.dialect.inline.__call__.call( this, m[2], /\\/ )[0]; + + var attrs = { alt: m[1], href: m[2] || "" }; + if ( m[4] !== undefined) + attrs.title = m[4]; + + return [ m[0].length, [ "img", attrs ] ]; + } + + // ![Alt text][id] + m = text.match( /^!\[(.*?)\][ \t]*\[(.*?)\]/ ); + + if ( m ) { + // We can't check if the reference is known here as it likely wont be + // found till after. Check it in md tree->hmtl tree conversion + return [ m[0].length, [ "img_ref", { alt: m[1], ref: m[2].toLowerCase(), text: m[0] } ] ]; + } + + // Just consume the '![' + return [ 2, "![" ]; + }, + + "[": function link( text ) { + // [link text](/path/to/img.jpg "Optional title") + // 1 2 3 4 <--- captures + var m = text.match( /^\[([\s\S]*?)\][ \t]*\([ \t]*(\S+)(?:[ \t]+(["'])(.*?)\3)?[ \t]*\)/ ); + + if ( m ) { + if ( m[2] && m[2][0] == '<' && m[2][m[2].length-1] == '>' ) + m[2] = m[2].substring( 1, m[2].length - 1 ); + + // Process escapes only + m[2] = this.dialect.inline.__call__.call( this, m[2], /\\/ )[0]; + + var attrs = { href: m[2] || "" }; + if ( m[4] !== undefined) + attrs.title = m[4]; + + return [ m[0].length, [ "link", attrs, m[1] ] ]; + } + + // [Alt text][id] + // [Alt text] [id] + // [id] + m = text.match( /^\[([\s\S]*?)\](?: ?\[(.*?)\])?/ ); + + if ( m ) { + // [id] case, text == id + if ( m[2] === undefined || m[2] === "" ) m[2] = m[1]; + + // We can't check if the reference is known here as it likely wont be + // found till after. Check it in md tree->hmtl tree conversion. + // Store the original so that conversion can revert if the ref isn't found. + return [ + m[ 0 ].length, + [ + "link_ref", + { + ref: m[ 2 ].toLowerCase(), + original: m[ 0 ] + }, + m[ 1 ] + ] + ]; + } + + // Just consume the '[' + return [ 1, "[" ]; + }, + + + "<": function autoLink( text ) { + var m; + + if ( ( m = text.match( /^<(?:((https?|ftp|mailto):[^>]+)|(.*?@.*?\.[a-zA-Z]+))>/ ) ) != null ) { + if ( m[3] ) { + return [ m[0].length, [ "link", { href: "mailto:" + m[3] }, m[3] ] ]; + + } + else if ( m[2] == "mailto" ) { + return [ m[0].length, [ "link", { href: m[1] }, m[1].substr("mailto:".length ) ] ]; + } + else + return [ m[0].length, [ "link", { href: m[1] }, m[1] ] ]; + } + + return [ 1, "<" ]; + }, + + "`": function inlineCode( text ) { + // Inline code block. as many backticks as you like to start it + // Always skip over the opening ticks. + var m = text.match( /(`+)(([\s\S]*?)\1)/ ); + + if ( m && m[2] ) + return [ m[1].length + m[2].length, [ "inlinecode", m[3] ] ]; + else { + // TODO: No matching end code found - warn! + return [ 1, "`" ]; + } + }, + + " \n": function lineBreak( text ) { + return [ 3, [ "linebreak" ] ]; + } + +} + +// Meta Helper/generator method for em and strong handling +function strong_em( tag, md ) { + + var state_slot = tag + "_state", + other_slot = tag == "strong" ? "em_state" : "strong_state"; + + function CloseTag(len) { + this.len_after = len; + this.name = "close_" + md; + } + + return function ( text, orig_match ) { + + if (this[state_slot][0] == md) { + // Most recent em is of this type + //D:this.debug("closing", md); + this[state_slot].shift(); + + // "Consume" everything to go back to the recrusion in the else-block below + return[ text.length, new CloseTag(text.length-md.length) ]; + } + else { + // Store a clone of the em/strong states + var other = this[other_slot].slice(), + state = this[state_slot].slice(); + + this[state_slot].unshift(md); + + //D:this.debug_indent += " "; + + // Recurse + var res = this.processInline( text.substr( md.length ) ); + //D:this.debug_indent = this.debug_indent.substr(2); + + var last = res[res.length - 1]; + + //D:this.debug("processInline from", tag + ": ", uneval( res ) ); + + var check = this[state_slot].shift(); + if (last instanceof CloseTag) { + res.pop(); + // We matched! Huzzah. + var consumed = text.length - last.len_after; + return [ consumed, [ tag ].concat(res) ]; + } + else { + // Restore the state of the other kind. We might have mistakenly closed it. + this[other_slot] = other; + this[state_slot] = state; + + // We can't reuse the processed result as it could have wrong parsing contexts in it. + return [ md.length, md ]; + } + } + } // End returned function +} + +Markdown.dialects.Gruber.inline["**"] = strong_em("strong", "**"); +Markdown.dialects.Gruber.inline["__"] = strong_em("strong", "__"); +Markdown.dialects.Gruber.inline["*"] = strong_em("em", "*"); +Markdown.dialects.Gruber.inline["_"] = strong_em("em", "_"); + + +// Build default order from insertion order. +Markdown.buildBlockOrder = function(d) { + var ord = []; + for ( var i in d ) { + if ( i == "__order__" || i == "__call__" ) continue; + ord.push( i ); + } + d.__order__ = ord; +} + +// Build patterns for inline matcher +Markdown.buildInlinePatterns = function(d) { + var patterns = []; + + for ( var i in d ) { + if (i == "__call__") continue; + var l = i.replace( /([\\.*+?|()\[\]{}])/g, "\\$1" ) + .replace( /\n/, "\\n" ); + patterns.push( i.length == 1 ? l : "(?:" + l + ")" ); + } + + patterns = patterns.join("|"); + //print("patterns:", uneval( patterns ) ); + + var fn = d.__call__; + d.__call__ = function(text, pattern) { + if (pattern != undefined) + return fn.call(this, text, pattern); + else + return fn.call(this, text, patterns); + } +} + +// Helper function to make sub-classing a dialect easier +Markdown.subclassDialect = function( d ) { + function Block() {}; + Block.prototype = d.block; + function Inline() {}; + Inline.prototype = d.inline; + + return { block: new Block(), inline: new Inline() }; +} + +Markdown.buildBlockOrder ( Markdown.dialects.Gruber.block ); +Markdown.buildInlinePatterns( Markdown.dialects.Gruber.inline ); + +Markdown.dialects.Maruku = Markdown.subclassDialect( Markdown.dialects.Gruber ); + +Markdown.dialects.Maruku.block.document_meta = function document_meta( block, next ) { + // we're only interested in the first block + if ( block.lineNumber > 1 ) return undefined; + + // document_meta blocks consist of one or more lines of `Key: Value\n` + if ( ! block.match( /^(?:\w+:.*\n)*\w+:.*$/ ) ) return undefined; + + // make an attribute node if it doesn't exist + if ( !extract_attr( this.tree ) ) { + this.tree.splice( 1, 0, {} ); + } + + var pairs = block.split( /\n/ ); + for ( p in pairs ) { + var m = pairs[ p ].match( /(\w+):\s*(.*)$/ ), + key = m[ 1 ].toLowerCase(), + value = m[ 2 ]; + + this.tree[ 1 ][ key ] = value; + } + + // document_meta produces no content! + return []; +} + +Markdown.dialects.Maruku.block.block_meta = function block_meta( block, next ) { + // check if the last line of the block is an meta hash + var m = block.match( /(^|\n) {0,3}\{:\s*((?:\\\}|[^\}])*)\s*\}$/ ); + if ( !m ) return undefined; + + // process the meta hash + var attr = process_meta_hash( m[ 2 ] ); + + // if we matched ^ then we need to apply meta to the previous block + if ( m[ 1 ] === "" ) { + var node = this.tree[ this.tree.length - 1 ], + hash = extract_attr( node ); + + // if the node is a string (rather than JsonML), bail + if ( typeof node === "string" ) return undefined; + + // create the attribute hash if it doesn't exist + if ( !hash ) { + hash = {}; + node.splice( 1, 0, hash ); + } + + // add the attributes in + for ( a in attr ) { + hash[ a ] = attr[ a ]; + } + + // return nothing so the meta hash is removed + return []; + } + + // pull the meta hash off the block and process what's left + var b = block.replace( /\n.*$/, "" ), + result = this.processBlock( b, [] ); + + // get or make the attributes hash + var hash = extract_attr( result[ 0 ] ); + if ( !hash ) { + hash = {}; + result[ 0 ].splice( 1, 0, hash ); + } + + // attach the attributes to the block + for ( a in attr ) { + hash[ a ] = attr[ a ]; + } + + return result; +} + +Markdown.dialects.Maruku.block.definition_list = function definition_list( block, next ) { + // one or more terms followed by one or more definitions, in a single block + var tight = /^((?:[^\s:].*\n)+):\s+([^]+)$/, + list = [ "dl" ]; + + // see if we're dealing with a tight or loose block + if ( ( m = block.match( tight ) ) ) { + // pull subsequent tight DL blocks out of `next` + var blocks = [ block ]; + while ( next.length && tight.exec( next[ 0 ] ) ) { + blocks.push( next.shift() ); + } + + for ( var b = 0; b < blocks.length; ++b ) { + var m = blocks[ b ].match( tight ), + terms = m[ 1 ].replace( /\n$/, "" ).split( /\n/ ), + defns = m[ 2 ].split( /\n:\s+/ ); + + // print( uneval( m ) ); + + for ( var i = 0; i < terms.length; ++i ) { + list.push( [ "dt", terms[ i ] ] ); + } + + for ( var i = 0; i < defns.length; ++i ) { + // run inline processing over the definition + list.push( [ "dd" ].concat( this.processInline( defns[ i ].replace( /(\n)\s+/, "$1" ) ) ) ); + } + } + } + else { + return undefined; + } + + return [ list ]; +} + +Markdown.dialects.Maruku.inline[ "{:" ] = function inline_meta( text, matches, out ) { + if ( !out.length ) { + return [ 2, "{:" ]; + } + + // get the preceeding element + var before = out[ out.length - 1 ]; + + if ( typeof before === "string" ) { + return [ 2, "{:" ]; + } + + // match a meta hash + var m = text.match( /^\{:\s*((?:\\\}|[^\}])*)\s*\}/ ); + + // no match, false alarm + if ( !m ) { + return [ 2, "{:" ]; + } + + // attach the attributes to the preceeding element + var meta = process_meta_hash( m[ 1 ] ), + attr = extract_attr( before ); + + if ( !attr ) { + attr = {}; + before.splice( 1, 0, attr ); + } + + for ( var k in meta ) { + attr[ k ] = meta[ k ]; + } + + // cut out the string and replace it with nothing + return [ m[ 0 ].length, "" ]; +} + +Markdown.buildBlockOrder ( Markdown.dialects.Maruku.block ); +Markdown.buildInlinePatterns( Markdown.dialects.Maruku.inline ); + +function extract_attr( jsonml ) { + return jsonml instanceof Array + && jsonml.length > 1 + && typeof jsonml[ 1 ] === "object" + && !( jsonml[ 1 ] instanceof Array ) + ? jsonml[ 1 ] + : undefined; +} + +function process_meta_hash( meta_string ) { + var meta = split_meta_hash( meta_string ), + attr = {}; + + for ( var i = 0; i < meta.length; ++i ) { + // id: #foo + if ( /^#/.test( meta[ i ] ) ) { + attr.id = meta[ i ].substring( 1 ); + } + // class: .foo + else if ( /^\./.test( meta[ i ] ) ) { + // if class already exists, append the new one + if ( attr['class'] ) { + attr['class'] = attr['class'] + meta[ i ].replace( /./, " " ); + } + else { + attr['class'] = meta[ i ].substring( 1 ); + } + } + // attribute: foo=bar + else if ( /=/.test( meta[ i ] ) ) { + var s = meta[ i ].split( /=/ ); + attr[ s[ 0 ] ] = s[ 1 ]; + } + } + + return attr; +} + +function split_meta_hash( meta_string ) { + var meta = meta_string.split( "" ), + parts = [ "" ], + in_quotes = false; + + while ( meta.length ) { + var letter = meta.shift(); + switch ( letter ) { + case " " : + // if we're in a quoted section, keep it + if ( in_quotes ) { + parts[ parts.length - 1 ] += letter; + } + // otherwise make a new part + else { + parts.push( "" ); + } + break; + case "'" : + case '"' : + // reverse the quotes and move straight on + in_quotes = !in_quotes; + break; + case "\\" : + // shift off the next letter to be used straight away. + // it was escaped so we'll keep it whatever it is + letter = meta.shift(); + default : + parts[ parts.length - 1 ] += letter; + break; + } + } + + return parts; +} + +/** + * renderJsonML( jsonml[, options] ) -> String + * - jsonml (Array): JsonML array to render to XML + * - options (Object): options + * + * Converts the given JsonML into well-formed XML. + * + * The options currently understood are: + * + * - root (Boolean): wether or not the root node should be included in the + * output, or just its children. The default `false` is to not include the + * root itself. + */ +expose.renderJsonML = function( jsonml, options ) { + options = options || {}; + // include the root element in the rendered output? + options.root = options.root || false; + + var content = []; + + if ( options.root ) { + content.push( render_tree( jsonml ) ); + } + else { + jsonml.shift(); // get rid of the tag + if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) { + jsonml.shift(); // get rid of the attributes + } + + while ( jsonml.length ) { + content.push( render_tree( jsonml.shift() ) ); + } + } + + return content.join( "\n\n" ); +} + +function escapeHTML( text ) { + return text.replace( /&/g, "&" ) + .replace( //g, ">" ) + .replace( /"/g, """ ) + .replace( /'/g, "'" ); +} + +function render_tree( jsonml ) { + // basic case + if ( typeof jsonml === "string" ) { + return escapeHTML( jsonml ); + } + + var tag = jsonml.shift(), + attributes = {}, + content = []; + + if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) { + attributes = jsonml.shift(); + } + + while ( jsonml.length ) { + content.push( arguments.callee( jsonml.shift() ) ); + } + + var tag_attrs = ""; + for ( var a in attributes ) { + tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"'; + } + + // be careful about adding whitespace here for inline elements + return "<"+ tag + tag_attrs + ">" + content.join( "" ) + ""; +} + +function convert_tree_to_html( tree, references ) { + // shallow clone + var jsonml = tree.slice( 0 ); + + // Clone attributes if the exist + var attrs = extract_attr( jsonml ); + if ( attrs ) { + jsonml[ 1 ] = {}; + for ( var i in attrs ) { + jsonml[ 1 ][ i ] = attrs[ i ]; + } + attrs = jsonml[ 1 ]; + } + + // basic case + if ( typeof jsonml === "string" ) { + return jsonml; + } + + // convert this node + switch ( jsonml[ 0 ] ) { + case "header": + jsonml[ 0 ] = "h" + jsonml[ 1 ].level; + delete jsonml[ 1 ].level; + break; + case "bulletlist": + jsonml[ 0 ] = "ul"; + break; + case "numberlist": + jsonml[ 0 ] = "ol"; + break; + case "listitem": + jsonml[ 0 ] = "li"; + break; + case "para": + jsonml[ 0 ] = "p"; + break; + case "markdown": + jsonml[ 0 ] = "html"; + if ( attrs ) delete attrs.references; + break; + case "code_block": + jsonml[ 0 ] = "pre"; + var i = attrs ? 2 : 1; + var code = [ "code" ]; + code.push.apply( code, jsonml.splice( i ) ); + jsonml[ i ] = code; + break; + case "inlinecode": + jsonml[ 0 ] = "code"; + break; + case "img": + jsonml[ 1 ].src = jsonml[ 1 ].href; + delete jsonml[ 1 ].href; + break; + case "linebreak": + jsonml[0] = "br"; + break; + case "link": + jsonml[ 0 ] = "a"; + break; + case "link_ref": + jsonml[ 0 ] = "a"; + + // grab this ref and clean up the attribute node + var ref = references[ attrs.ref ]; + + // if the reference exists, make the link + if ( ref ) { + delete attrs.ref; + + // add in the href and title, if present + attrs.href = ref.href; + if ( ref.title ) { + attrs.title = ref.title; + } + + // get rid of the unneeded original text + delete attrs.original; + } + // the reference doesn't exist, so revert to plain text + else { + return attrs.original; + } + break; + } + + // convert all the children + var i = 1; + + // deal with the attribute node, if it exists + if ( attrs ) { + // if there are keys, skip over it + for ( var key in jsonml[ 1 ] ) { + i = 2; + } + // if there aren't, remove it + if ( i === 1 ) { + jsonml.splice( i, 1 ); + } + } + + for ( ; i < jsonml.length; ++i ) { + jsonml[ i ] = arguments.callee( jsonml[ i ], references ); + } + + return jsonml; +} + + +// merges adjacent text nodes into a single node +function merge_text_nodes( jsonml ) { + // skip the tag name and attribute hash + var i = extract_attr( jsonml ) ? 2 : 1; + + while ( i < jsonml.length ) { + // if it's a string check the next item too + if ( typeof jsonml[ i ] === "string" ) { + if ( i + 1 < jsonml.length && typeof jsonml[ i + 1 ] === "string" ) { + // merge the second string into the first and remove it + jsonml[ i ] += jsonml.splice( i + 1, 1 )[ 0 ]; + } + else { + ++i; + } + } + // if it's not a string recurse + else { + arguments.callee( jsonml[ i ] ); + ++i; + } + } +} + +} )( (function() { + if ( typeof exports === "undefined" ) { + window.markdown = {}; + return window.markdown; + } + else { + return exports; + } +} )() ); diff --git a/node_modules/markdown/package.json b/node_modules/markdown/package.json new file mode 100644 index 00000000..9fc895fd --- /dev/null +++ b/node_modules/markdown/package.json @@ -0,0 +1,42 @@ +{ + "name" : "markdown", + "version" : "0.2.1", + "description" : "A sensible Markdown parser for javascript", + "keywords" : [ "markdown", "text processing", "ast" ], + "maintainers" : [ + { + "name" : "Dominic Baggott", + "email" : "dominic.baggott@gmail.com", + "web" : "http://evilstreak.co.uk" + }, + { + "name" : "Ash Berlin", + "email" : "ash_markdownjs@firemirror.com", + "web" : "http://ashberlin.com" + } + ], + "contributors" : [ + { + "name" : "Dominic Baggott", + "email" : "dominic.baggott@gmail.com", + "web" : "http://evilstreak.co.uk" + }, + { + "name" : "Ash Berlin", + "email" : "ash_markdownjs@firemirror.com", + "web" : "http://ashberlin.com" + } + ], + "bugs" : "http://github.com/evilstreak/markdown-js/issues", + "licenses" : [ + { + "type" : "MIT", + "url" : "http://www.opensource.org/licenses/mit-license.php" + } + ], + "main" : "./lib/index.js", + "repository" : { + "type" : "git", + "url" : "git://github.com/evilstreak/markdown-js.git" + } +} diff --git a/node_modules/markdown/seed.yml b/node_modules/markdown/seed.yml new file mode 100644 index 00000000..a15b2290 --- /dev/null +++ b/node_modules/markdown/seed.yml @@ -0,0 +1,5 @@ +--- + name: markdown-js + description: JavaScript implementation of Markdown + tags: markdown parser + version: 0.1.2 diff --git a/node_modules/markdown/test/features.t.js b/node_modules/markdown/test/features.t.js new file mode 100644 index 00000000..d20f3dc8 --- /dev/null +++ b/node_modules/markdown/test/features.t.js @@ -0,0 +1,84 @@ +const test = require('test'), + asserts = test.asserts, + fs = require( "fs-base" ), + markdown = require( "markdown" ), + args = require( "system" ).args.splice( 1 ); + +function test_dialect( dialect, features ) { + var path = module.resource.resolve( "features" ), + dialect_test = exports[ "test_" + dialect ] = {}; + + for ( var f in features ) { + ( function( feature ) { + dialect_test[ "test_" + feature ] = function() { + var test_path = path + feature + "/"; + + // grab all the test files in this feature + var tests = fs.list( test_path ); + + // filter to only the raw files + tests = tests.filter( function( x ) x.match( /\.text$/ ) ); + + // remove the extensions + tests = tests.map( function( x ) x.replace( /\.text$/, "" ) ); + + for ( var t in tests ) { + // load the raw text + var test_name = tests[ t ].substring( tests[ t ].lastIndexOf( "/" ) + 1 ), + text_file = fs.rawOpen( test_path + tests[ t ] + ".text", "r" ), + text = text_file.readWhole(); + text_file.close(); + + // load the target output + if ( fs.isFile( test_path + tests[ t ] + ".json" ) ) { + try { + var json_file = fs.rawOpen( test_path + tests[ t ] + ".json", "r" ), + json = JSON.parse( json_file.readWhole() ); + json_file.close(); + + var output = markdown.toHTMLTree( text, dialect ); + asserts.same( output, json, test_name ); + } + catch( e ) { + asserts.ok( 0, "Failed with error on " + test_name + ": " + e ); + if ( e.stack ) + asserts.diag( e.stack ); + } + } + else { + asserts.ok( 0, "No target output for " + test_name ); + } + } + } + } )( features[ f ] ); + } +} + +if ( require.main === module ) { + var dialects = {}; + dialects.Gruber = [ + "blockquotes", + "code", + "emphasis", + "headers", + "horizontal_rules", + "images", + "linebreaks", + "links", + "lists" + ]; + + dialects.Maruku = dialects.Gruber.slice( 0 ); + dialects.Maruku.push( "meta", "definition_lists" ); + + // TODO if dialects/features were passed on the command line, filter to them + // if ( args.length ) { + // features = features.filter( function( x ) args.indexOf( x ) !== -1 ); + // } + + for ( d in dialects ) { + test_dialect( d, dialects[ d ] ); + } + + test.runner( exports ); +} diff --git a/node_modules/markdown/test/features/blockquotes/contains_code.json b/node_modules/markdown/test/features/blockquotes/contains_code.json new file mode 100644 index 00000000..c02dd38f --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/contains_code.json @@ -0,0 +1,15 @@ +["html", + ["blockquote", + ["p", + "There's a code block in here:" + ], + ["pre", + ["code", + "SET foo = TRUE\n\nIF foo GOTO 10" + ] + ], + ["p", + "Wasn't that nice?" + ] + ] +] diff --git a/node_modules/markdown/test/features/blockquotes/contains_code.text b/node_modules/markdown/test/features/blockquotes/contains_code.text new file mode 100644 index 00000000..a9f42cff --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/contains_code.text @@ -0,0 +1,7 @@ +> There's a code block in here: +> +> SET foo = TRUE +> +> IF foo GOTO 10 +> +> Wasn't that nice? diff --git a/node_modules/markdown/test/features/blockquotes/lazy_wrapping.json b/node_modules/markdown/test/features/blockquotes/lazy_wrapping.json new file mode 100644 index 00000000..18302cce --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/lazy_wrapping.json @@ -0,0 +1,10 @@ +["html", + ["blockquote", + ["p", + "If you're too lazy\nto wrap your code nicely" + ], + ["p", + "This will still work" + ] + ] +] diff --git a/node_modules/markdown/test/features/blockquotes/lazy_wrapping.text b/node_modules/markdown/test/features/blockquotes/lazy_wrapping.text new file mode 100644 index 00000000..eba02ada --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/lazy_wrapping.text @@ -0,0 +1,4 @@ +> If you're too lazy +to wrap your code nicely + +> This will still work diff --git a/node_modules/markdown/test/features/blockquotes/leading_paras.json b/node_modules/markdown/test/features/blockquotes/leading_paras.json new file mode 100644 index 00000000..2911f083 --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/leading_paras.json @@ -0,0 +1,18 @@ +["html", + ["p", + "Amy wrote:" + ], + ["blockquote", + ["p", + "No wai?" + ] + ], + ["p", + "Bob wrote:" + ], + ["blockquote", + ["p", + "Ya rly!" + ] + ] +] diff --git a/node_modules/markdown/test/features/blockquotes/leading_paras.text b/node_modules/markdown/test/features/blockquotes/leading_paras.text new file mode 100644 index 00000000..712b3b89 --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/leading_paras.text @@ -0,0 +1,5 @@ +Amy wrote: +> No wai? + +Bob wrote: +> Ya rly! diff --git a/node_modules/markdown/test/features/blockquotes/nested.json b/node_modules/markdown/test/features/blockquotes/nested.json new file mode 100644 index 00000000..c49536b8 --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/nested.json @@ -0,0 +1,15 @@ +["html", + ["blockquote", + ["p", + "One" + ], + ["blockquote", + ["p", + "Two" + ] + ], + ["p", + "Three" + ] + ] +] diff --git a/node_modules/markdown/test/features/blockquotes/nested.text b/node_modules/markdown/test/features/blockquotes/nested.text new file mode 100644 index 00000000..cec53f74 --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/nested.text @@ -0,0 +1,5 @@ +> One +> +> > Two +> +> Three diff --git a/node_modules/markdown/test/features/blockquotes/simple.json b/node_modules/markdown/test/features/blockquotes/simple.json new file mode 100644 index 00000000..8771e42f --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/simple.json @@ -0,0 +1,7 @@ +["html", + ["blockquote", + ["p", + "Blockquote" + ] + ] +] diff --git a/node_modules/markdown/test/features/blockquotes/simple.text b/node_modules/markdown/test/features/blockquotes/simple.text new file mode 100644 index 00000000..74045e7e --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/simple.text @@ -0,0 +1 @@ +> Blockquote diff --git a/node_modules/markdown/test/features/blockquotes/spaceless.json b/node_modules/markdown/test/features/blockquotes/spaceless.json new file mode 100644 index 00000000..46e1e3dd --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/spaceless.json @@ -0,0 +1,7 @@ +["html", + ["blockquote", + ["p", + "blockquote\nwithout spaces" + ] + ] +] diff --git a/node_modules/markdown/test/features/blockquotes/spaceless.text b/node_modules/markdown/test/features/blockquotes/spaceless.text new file mode 100644 index 00000000..31ae9fdb --- /dev/null +++ b/node_modules/markdown/test/features/blockquotes/spaceless.text @@ -0,0 +1,2 @@ +>blockquote +>without spaces diff --git a/node_modules/markdown/test/features/code/blank_lines.json b/node_modules/markdown/test/features/code/blank_lines.json new file mode 100644 index 00000000..84ed59a6 --- /dev/null +++ b/node_modules/markdown/test/features/code/blank_lines.json @@ -0,0 +1,26 @@ +["html", + ["p", + "This block is composed of three lines:" + ], + ["pre", + ["code", + "one\n\nthree" + ] + ], + ["p", + "This block is composed of 5" + ], + ["pre", + ["code", + "one\n\n\nfour" + ] + ], + ["p", + "This block is composed of 2" + ], + ["pre", + ["code", + "two" + ] + ] +] diff --git a/node_modules/markdown/test/features/code/blank_lines.text b/node_modules/markdown/test/features/code/blank_lines.text new file mode 100644 index 00000000..0f2d7c32 --- /dev/null +++ b/node_modules/markdown/test/features/code/blank_lines.text @@ -0,0 +1,22 @@ +This block is composed of three lines: + + one + + three + +This block is composed of 5 + + + one + + + four + + +This block is composed of 2 + + + two + + + diff --git a/node_modules/markdown/test/features/code/block.json b/node_modules/markdown/test/features/code/block.json new file mode 100644 index 00000000..425b8b33 --- /dev/null +++ b/node_modules/markdown/test/features/code/block.json @@ -0,0 +1,10 @@ +["html", + ["p", + "Here is an example of AppleScript:" + ], + ["pre", + ["code", + "tell application \"Foo\"\n beep\nend tell\n\ttab" + ] + ] +] diff --git a/node_modules/markdown/test/features/code/block.text b/node_modules/markdown/test/features/code/block.text new file mode 100644 index 00000000..3656212a --- /dev/null +++ b/node_modules/markdown/test/features/code/block.text @@ -0,0 +1,7 @@ +Here is an example of AppleScript: + + tell application "Foo" + beep + end tell + tab + diff --git a/node_modules/markdown/test/features/code/embedded_backtick.json b/node_modules/markdown/test/features/code/embedded_backtick.json new file mode 100644 index 00000000..17078c5d --- /dev/null +++ b/node_modules/markdown/test/features/code/embedded_backtick.json @@ -0,0 +1,8 @@ +["html", + ["p", + "This is a ", + ["code", + "code span with an `embedded` backtick"], + "." + ] +] diff --git a/node_modules/markdown/test/features/code/embedded_backtick.text b/node_modules/markdown/test/features/code/embedded_backtick.text new file mode 100644 index 00000000..65313065 --- /dev/null +++ b/node_modules/markdown/test/features/code/embedded_backtick.text @@ -0,0 +1 @@ +This is a ``code span with an `embedded` backtick``. diff --git a/node_modules/markdown/test/features/code/horizontal_rules.json b/node_modules/markdown/test/features/code/horizontal_rules.json new file mode 100644 index 00000000..343f3a6f --- /dev/null +++ b/node_modules/markdown/test/features/code/horizontal_rules.json @@ -0,0 +1,7 @@ +["html", + ["pre", + ["code", + "fsfsfsf\n* * *\n\n***\n\n*****\n\n- - -\n\n---------------------------------------" + ] + ] +] diff --git a/node_modules/markdown/test/features/code/horizontal_rules.text b/node_modules/markdown/test/features/code/horizontal_rules.text new file mode 100644 index 00000000..394a6139 --- /dev/null +++ b/node_modules/markdown/test/features/code/horizontal_rules.text @@ -0,0 +1,10 @@ + fsfsfsf + * * * + + *** + + ***** + + - - - + + --------------------------------------- diff --git a/node_modules/markdown/test/features/code/inline.json b/node_modules/markdown/test/features/code/inline.json new file mode 100644 index 00000000..75a92134 --- /dev/null +++ b/node_modules/markdown/test/features/code/inline.json @@ -0,0 +1,8 @@ +["html", + ["p", + ["code", + "This" + ], + " is a code span." + ] +] diff --git a/node_modules/markdown/test/features/code/inline.text b/node_modules/markdown/test/features/code/inline.text new file mode 100644 index 00000000..7f18b224 --- /dev/null +++ b/node_modules/markdown/test/features/code/inline.text @@ -0,0 +1 @@ +`This` is a code span. diff --git a/node_modules/markdown/test/features/code/inline_multiline.json b/node_modules/markdown/test/features/code/inline_multiline.json new file mode 100644 index 00000000..d9ae07ef --- /dev/null +++ b/node_modules/markdown/test/features/code/inline_multiline.json @@ -0,0 +1,9 @@ +["html", + ["p", + "foo ", + ["code", + "code\ncode" + ], + " bar" + ] +] diff --git a/node_modules/markdown/test/features/code/inline_multiline.text b/node_modules/markdown/test/features/code/inline_multiline.text new file mode 100644 index 00000000..13c8d604 --- /dev/null +++ b/node_modules/markdown/test/features/code/inline_multiline.text @@ -0,0 +1,2 @@ +foo `code +code` bar diff --git a/node_modules/markdown/test/features/code/trailing_para.json b/node_modules/markdown/test/features/code/trailing_para.json new file mode 100644 index 00000000..fb02131f --- /dev/null +++ b/node_modules/markdown/test/features/code/trailing_para.json @@ -0,0 +1,13 @@ +["html", + ["p", + "Paragraph above" + ], + ["pre", + ["code", + "Code block" + ] + ], + ["p", + "Paragraph below" + ] +] diff --git a/node_modules/markdown/test/features/code/trailing_para.text b/node_modules/markdown/test/features/code/trailing_para.text new file mode 100644 index 00000000..abca8d8b --- /dev/null +++ b/node_modules/markdown/test/features/code/trailing_para.text @@ -0,0 +1,4 @@ +Paragraph above + + Code block +Paragraph below diff --git a/node_modules/markdown/test/features/definition_lists/inline.json b/node_modules/markdown/test/features/definition_lists/inline.json new file mode 100644 index 00000000..2e9d3cb7 --- /dev/null +++ b/node_modules/markdown/test/features/definition_lists/inline.json @@ -0,0 +1,22 @@ +["html", + ["dl", + ["dt", + "a term" + ], + ["dd", + ["em", + "emphasised" + ], + " definition." + ], + ["dt", + "another term" + ], + ["dd", + ["strong", + "strong" + ], + " definition." + ] + ] +] diff --git a/node_modules/markdown/test/features/definition_lists/inline.text b/node_modules/markdown/test/features/definition_lists/inline.text new file mode 100644 index 00000000..b79dbc72 --- /dev/null +++ b/node_modules/markdown/test/features/definition_lists/inline.text @@ -0,0 +1,5 @@ +a term +: *emphasised* definition. + +another term +: **strong** definition. diff --git a/node_modules/markdown/test/features/definition_lists/long.json b/node_modules/markdown/test/features/definition_lists/long.json new file mode 100644 index 00000000..3dfdd2f9 --- /dev/null +++ b/node_modules/markdown/test/features/definition_lists/long.json @@ -0,0 +1,16 @@ +["html", + ["dl", + ["dt", + "first term" + ], + ["dd", + "the quick brown fox jumps\nover the lazy dog" + ], + ["dt", + "second term" + ], + ["dd", + "pack my box with five\ndozen liquor jugs" + ] + ] +] diff --git a/node_modules/markdown/test/features/definition_lists/long.text b/node_modules/markdown/test/features/definition_lists/long.text new file mode 100644 index 00000000..001df33d --- /dev/null +++ b/node_modules/markdown/test/features/definition_lists/long.text @@ -0,0 +1,7 @@ +first term +: the quick brown fox jumps + over the lazy dog + +second term +: pack my box with five +dozen liquor jugs diff --git a/node_modules/markdown/test/features/definition_lists/multiple_definitions.json b/node_modules/markdown/test/features/definition_lists/multiple_definitions.json new file mode 100644 index 00000000..6bb3d59c --- /dev/null +++ b/node_modules/markdown/test/features/definition_lists/multiple_definitions.json @@ -0,0 +1,28 @@ +["html", + ["dl", + ["dt", + "fruit" + ], + ["dd", + "apple" + ], + ["dd", + "banana" + ], + ["dd", + "pear" + ], + ["dt", + "animal" + ], + ["dd", + "cow" + ], + ["dd", + "duck" + ], + ["dd", + "horse" + ] + ] +] diff --git a/node_modules/markdown/test/features/definition_lists/multiple_definitions.text b/node_modules/markdown/test/features/definition_lists/multiple_definitions.text new file mode 100644 index 00000000..b6b0ecae --- /dev/null +++ b/node_modules/markdown/test/features/definition_lists/multiple_definitions.text @@ -0,0 +1,9 @@ +fruit +: apple +: banana +: pear + +animal +: cow +: duck +: horse diff --git a/node_modules/markdown/test/features/definition_lists/multiple_terms.json b/node_modules/markdown/test/features/definition_lists/multiple_terms.json new file mode 100644 index 00000000..4cf7cd86 --- /dev/null +++ b/node_modules/markdown/test/features/definition_lists/multiple_terms.json @@ -0,0 +1,22 @@ +["html", + ["dl", + ["dt", + "fruit" + ], + ["dt", + "vegetable" + ], + ["dd", + "tomato" + ], + ["dt", + "animal" + ], + ["dt", + "mineral" + ], + ["dd", + "pet rock" + ] + ] +] diff --git a/node_modules/markdown/test/features/definition_lists/multiple_terms.text b/node_modules/markdown/test/features/definition_lists/multiple_terms.text new file mode 100644 index 00000000..e5447bf7 --- /dev/null +++ b/node_modules/markdown/test/features/definition_lists/multiple_terms.text @@ -0,0 +1,7 @@ +fruit +vegetable +: tomato + +animal +mineral +: pet rock diff --git a/node_modules/markdown/test/features/definition_lists/tight.json b/node_modules/markdown/test/features/definition_lists/tight.json new file mode 100644 index 00000000..a38e42bf --- /dev/null +++ b/node_modules/markdown/test/features/definition_lists/tight.json @@ -0,0 +1,22 @@ +["html", + ["dl", + ["dt", + "one" + ], + ["dd", + "alpha" + ], + ["dt", + "two" + ], + ["dd", + "beta" + ], + ["dt", + "three" + ], + ["dd", + "gamma" + ] + ] +] diff --git a/node_modules/markdown/test/features/definition_lists/tight.text b/node_modules/markdown/test/features/definition_lists/tight.text new file mode 100644 index 00000000..62764129 --- /dev/null +++ b/node_modules/markdown/test/features/definition_lists/tight.text @@ -0,0 +1,8 @@ +one +: alpha + +two +: beta + +three +: gamma diff --git a/node_modules/markdown/test/features/emphasis/multiple_lines.json b/node_modules/markdown/test/features/emphasis/multiple_lines.json new file mode 100644 index 00000000..193e11ad --- /dev/null +++ b/node_modules/markdown/test/features/emphasis/multiple_lines.json @@ -0,0 +1,9 @@ +["html", + ["p", + "You can ", + ["em", + "start emphasis on one line,\nand finish it" + ], + " on another." + ] +] diff --git a/node_modules/markdown/test/features/emphasis/multiple_lines.text b/node_modules/markdown/test/features/emphasis/multiple_lines.text new file mode 100644 index 00000000..9a6b98c6 --- /dev/null +++ b/node_modules/markdown/test/features/emphasis/multiple_lines.text @@ -0,0 +1,2 @@ +You can *start emphasis on one line, +and finish it* on another. diff --git a/node_modules/markdown/test/features/emphasis/nested.json b/node_modules/markdown/test/features/emphasis/nested.json new file mode 100644 index 00000000..0d61d950 --- /dev/null +++ b/node_modules/markdown/test/features/emphasis/nested.json @@ -0,0 +1,24 @@ +["html", + ["p", + "You can ", + ["strong", + "nest ", + ["em", + "em" + ], + " inside strong" + ], + "." + ], + ["p", + "You can ", + ["em", + "nest ", + ["strong", + "strong" + ], + " inside em" + ], + "." + ] +] diff --git a/node_modules/markdown/test/features/emphasis/nested.text b/node_modules/markdown/test/features/emphasis/nested.text new file mode 100644 index 00000000..1291b095 --- /dev/null +++ b/node_modules/markdown/test/features/emphasis/nested.text @@ -0,0 +1,3 @@ +You can **nest *em* inside strong**. + +You can *nest **strong** inside em*. diff --git a/node_modules/markdown/test/features/emphasis/simple.json b/node_modules/markdown/test/features/emphasis/simple.json new file mode 100644 index 00000000..1da89e58 --- /dev/null +++ b/node_modules/markdown/test/features/emphasis/simple.json @@ -0,0 +1,24 @@ +["html", + ["p", + "Emphasis can be ", + ["em", + "weak" + ], + " or ", + ["strong", + "strong" + ], + "." + ], + ["p", + "It can ", + ["em", + "even" + ], + " use ", + ["strong", + "underscores" + ], + "." + ] +] diff --git a/node_modules/markdown/test/features/emphasis/simple.text b/node_modules/markdown/test/features/emphasis/simple.text new file mode 100644 index 00000000..5328d996 --- /dev/null +++ b/node_modules/markdown/test/features/emphasis/simple.text @@ -0,0 +1,3 @@ +Emphasis can be *weak* or **strong**. + +It can _even_ use __underscores__. diff --git a/node_modules/markdown/test/features/headers/atx.json b/node_modules/markdown/test/features/headers/atx.json new file mode 100644 index 00000000..df472276 --- /dev/null +++ b/node_modules/markdown/test/features/headers/atx.json @@ -0,0 +1,20 @@ +["html", + ["h1", + "One" + ], + ["h2", + "Two" + ], + ["h3", + "Three" + ], + ["h4", + "Four" + ], + ["h5", + "Five" + ], + ["h6", + "Six" + ] +] diff --git a/node_modules/markdown/test/features/headers/atx.text b/node_modules/markdown/test/features/headers/atx.text new file mode 100644 index 00000000..541c9d3f --- /dev/null +++ b/node_modules/markdown/test/features/headers/atx.text @@ -0,0 +1,11 @@ +# One + +## Two + +### Three + +#### Four + +##### Five + +###### Six diff --git a/node_modules/markdown/test/features/headers/atx_closing_hashes.json b/node_modules/markdown/test/features/headers/atx_closing_hashes.json new file mode 100644 index 00000000..acb205b5 --- /dev/null +++ b/node_modules/markdown/test/features/headers/atx_closing_hashes.json @@ -0,0 +1,11 @@ +["html", + ["h1", + "One" + ], + ["h2", + "Two" + ], + ["h3", + "Three" + ] +] diff --git a/node_modules/markdown/test/features/headers/atx_closing_hashes.text b/node_modules/markdown/test/features/headers/atx_closing_hashes.text new file mode 100644 index 00000000..4734f433 --- /dev/null +++ b/node_modules/markdown/test/features/headers/atx_closing_hashes.text @@ -0,0 +1,5 @@ +# One # + +## Two ##### + +### Three ## diff --git a/node_modules/markdown/test/features/headers/setext.json b/node_modules/markdown/test/features/headers/setext.json new file mode 100644 index 00000000..f5502023 --- /dev/null +++ b/node_modules/markdown/test/features/headers/setext.json @@ -0,0 +1,8 @@ +["html", + ["h1", + "One" + ], + ["h2", + "Two" + ] +] diff --git a/node_modules/markdown/test/features/headers/setext.text b/node_modules/markdown/test/features/headers/setext.text new file mode 100644 index 00000000..58b746d3 --- /dev/null +++ b/node_modules/markdown/test/features/headers/setext.text @@ -0,0 +1,5 @@ +One +=== + +Two +--- diff --git a/node_modules/markdown/test/features/headers/trailing_paras.json b/node_modules/markdown/test/features/headers/trailing_paras.json new file mode 100644 index 00000000..f5ec1c3d --- /dev/null +++ b/node_modules/markdown/test/features/headers/trailing_paras.json @@ -0,0 +1,20 @@ +["html", + ["h1", + "Header" + ], + ["p", + "Paragraph" + ], + ["h2", + "Header" + ], + ["p", + "Paragraph" + ], + ["h3", + "Header" + ], + ["p", + "Paragraph" + ] +] diff --git a/node_modules/markdown/test/features/headers/trailing_paras.text b/node_modules/markdown/test/features/headers/trailing_paras.text new file mode 100644 index 00000000..6cac1994 --- /dev/null +++ b/node_modules/markdown/test/features/headers/trailing_paras.text @@ -0,0 +1,10 @@ +Header +====== +Paragraph + +Header +------ +Paragraph + +### Header +Paragraph diff --git a/node_modules/markdown/test/features/horizontal_rules/abutting_blocks.json b/node_modules/markdown/test/features/horizontal_rules/abutting_blocks.json new file mode 100644 index 00000000..e08b7b28 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/abutting_blocks.json @@ -0,0 +1,17 @@ +["html", + ["p", + "para" + ], + ["hr"], + ["ul", + ["li", + "list" + ] + ], + ["hr"], + ["blockquote", + ["p", + "blockquote" + ] + ] +] diff --git a/node_modules/markdown/test/features/horizontal_rules/abutting_blocks.text b/node_modules/markdown/test/features/horizontal_rules/abutting_blocks.text new file mode 100644 index 00000000..8762e293 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/abutting_blocks.text @@ -0,0 +1,5 @@ +para +*** +* list + - - - +> blockquote diff --git a/node_modules/markdown/test/features/horizontal_rules/dashes.json b/node_modules/markdown/test/features/horizontal_rules/dashes.json new file mode 100644 index 00000000..69389324 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/dashes.json @@ -0,0 +1,3 @@ +["html", + ["hr"] +] diff --git a/node_modules/markdown/test/features/horizontal_rules/dashes.text b/node_modules/markdown/test/features/horizontal_rules/dashes.text new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/dashes.text @@ -0,0 +1 @@ +--- diff --git a/node_modules/markdown/test/features/horizontal_rules/leading_spaces.json b/node_modules/markdown/test/features/horizontal_rules/leading_spaces.json new file mode 100644 index 00000000..69389324 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/leading_spaces.json @@ -0,0 +1,3 @@ +["html", + ["hr"] +] diff --git a/node_modules/markdown/test/features/horizontal_rules/leading_spaces.text b/node_modules/markdown/test/features/horizontal_rules/leading_spaces.text new file mode 100644 index 00000000..366af230 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/leading_spaces.text @@ -0,0 +1 @@ + * * * diff --git a/node_modules/markdown/test/features/horizontal_rules/long.json b/node_modules/markdown/test/features/horizontal_rules/long.json new file mode 100644 index 00000000..69389324 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/long.json @@ -0,0 +1,3 @@ +["html", + ["hr"] +] diff --git a/node_modules/markdown/test/features/horizontal_rules/long.text b/node_modules/markdown/test/features/horizontal_rules/long.text new file mode 100644 index 00000000..32727f7b --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/long.text @@ -0,0 +1 @@ +********************* diff --git a/node_modules/markdown/test/features/horizontal_rules/long_loose.json b/node_modules/markdown/test/features/horizontal_rules/long_loose.json new file mode 100644 index 00000000..69389324 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/long_loose.json @@ -0,0 +1,3 @@ +["html", + ["hr"] +] diff --git a/node_modules/markdown/test/features/horizontal_rules/long_loose.text b/node_modules/markdown/test/features/horizontal_rules/long_loose.text new file mode 100644 index 00000000..5669cff2 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/long_loose.text @@ -0,0 +1 @@ +* * * * * * * * * * * diff --git a/node_modules/markdown/test/features/horizontal_rules/loose_dashes.json b/node_modules/markdown/test/features/horizontal_rules/loose_dashes.json new file mode 100644 index 00000000..69389324 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/loose_dashes.json @@ -0,0 +1,3 @@ +["html", + ["hr"] +] diff --git a/node_modules/markdown/test/features/horizontal_rules/loose_dashes.text b/node_modules/markdown/test/features/horizontal_rules/loose_dashes.text new file mode 100644 index 00000000..75fb4cdc --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/loose_dashes.text @@ -0,0 +1 @@ +- - - diff --git a/node_modules/markdown/test/features/horizontal_rules/loose_stars.json b/node_modules/markdown/test/features/horizontal_rules/loose_stars.json new file mode 100644 index 00000000..69389324 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/loose_stars.json @@ -0,0 +1,3 @@ +["html", + ["hr"] +] diff --git a/node_modules/markdown/test/features/horizontal_rules/loose_stars.text b/node_modules/markdown/test/features/horizontal_rules/loose_stars.text new file mode 100644 index 00000000..96b474ae --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/loose_stars.text @@ -0,0 +1 @@ +* * * diff --git a/node_modules/markdown/test/features/horizontal_rules/loose_underscores.json b/node_modules/markdown/test/features/horizontal_rules/loose_underscores.json new file mode 100644 index 00000000..69389324 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/loose_underscores.json @@ -0,0 +1,3 @@ +["html", + ["hr"] +] diff --git a/node_modules/markdown/test/features/horizontal_rules/loose_underscores.text b/node_modules/markdown/test/features/horizontal_rules/loose_underscores.text new file mode 100644 index 00000000..f45d2aa4 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/loose_underscores.text @@ -0,0 +1 @@ +_ _ _ diff --git a/node_modules/markdown/test/features/horizontal_rules/stars.json b/node_modules/markdown/test/features/horizontal_rules/stars.json new file mode 100644 index 00000000..69389324 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/stars.json @@ -0,0 +1,3 @@ +["html", + ["hr"] +] diff --git a/node_modules/markdown/test/features/horizontal_rules/stars.text b/node_modules/markdown/test/features/horizontal_rules/stars.text new file mode 100644 index 00000000..6a7e4527 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/stars.text @@ -0,0 +1 @@ +*** diff --git a/node_modules/markdown/test/features/horizontal_rules/underscores.json b/node_modules/markdown/test/features/horizontal_rules/underscores.json new file mode 100644 index 00000000..69389324 --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/underscores.json @@ -0,0 +1,3 @@ +["html", + ["hr"] +] diff --git a/node_modules/markdown/test/features/horizontal_rules/underscores.text b/node_modules/markdown/test/features/horizontal_rules/underscores.text new file mode 100644 index 00000000..88f351dc --- /dev/null +++ b/node_modules/markdown/test/features/horizontal_rules/underscores.text @@ -0,0 +1 @@ +___ diff --git a/node_modules/markdown/test/features/images/basic.json b/node_modules/markdown/test/features/images/basic.json new file mode 100644 index 00000000..57bb1451 --- /dev/null +++ b/node_modules/markdown/test/features/images/basic.json @@ -0,0 +1,8 @@ +["html", + ["p", + ["img", { + "src": "/path/to/img.jpg", + "alt": "Alt text" + } ] + ] +] diff --git a/node_modules/markdown/test/features/images/basic.text b/node_modules/markdown/test/features/images/basic.text new file mode 100644 index 00000000..7691a61c --- /dev/null +++ b/node_modules/markdown/test/features/images/basic.text @@ -0,0 +1 @@ +![Alt text](/path/to/img.jpg) diff --git a/node_modules/markdown/test/features/images/crotcheted_url.json b/node_modules/markdown/test/features/images/crotcheted_url.json new file mode 100644 index 00000000..456b6e74 --- /dev/null +++ b/node_modules/markdown/test/features/images/crotcheted_url.json @@ -0,0 +1,8 @@ +["html", + ["p", + ["img", { + "src": "/url/", + "alt": "alt text" + } ] + ] +] diff --git a/node_modules/markdown/test/features/images/crotcheted_url.text b/node_modules/markdown/test/features/images/crotcheted_url.text new file mode 100644 index 00000000..a63d32b3 --- /dev/null +++ b/node_modules/markdown/test/features/images/crotcheted_url.text @@ -0,0 +1 @@ +![alt text]() diff --git a/node_modules/markdown/test/features/images/crotcheted_url_with_title.json b/node_modules/markdown/test/features/images/crotcheted_url_with_title.json new file mode 100644 index 00000000..2d1cb3e3 --- /dev/null +++ b/node_modules/markdown/test/features/images/crotcheted_url_with_title.json @@ -0,0 +1,9 @@ +["html", + ["p", + ["img", { + "src": "/url/", + "alt": "alt text", + "title": "with a title" + } ] + ] +] diff --git a/node_modules/markdown/test/features/images/crotcheted_url_with_title.text b/node_modules/markdown/test/features/images/crotcheted_url_with_title.text new file mode 100644 index 00000000..e04a61d5 --- /dev/null +++ b/node_modules/markdown/test/features/images/crotcheted_url_with_title.text @@ -0,0 +1 @@ +![alt text]( "with a title") diff --git a/node_modules/markdown/test/features/images/empty.json b/node_modules/markdown/test/features/images/empty.json new file mode 100644 index 00000000..3c531695 --- /dev/null +++ b/node_modules/markdown/test/features/images/empty.json @@ -0,0 +1,8 @@ +["html", + ["p", + ["img", { + "src": "", + "alt": "Empty" + } ] + ] +] diff --git a/node_modules/markdown/test/features/images/empty.text b/node_modules/markdown/test/features/images/empty.text new file mode 100644 index 00000000..8f3ee484 --- /dev/null +++ b/node_modules/markdown/test/features/images/empty.text @@ -0,0 +1 @@ +![Empty]() diff --git a/node_modules/markdown/test/features/images/spaces_round_title.json b/node_modules/markdown/test/features/images/spaces_round_title.json new file mode 100644 index 00000000..a19cb6af --- /dev/null +++ b/node_modules/markdown/test/features/images/spaces_round_title.json @@ -0,0 +1,9 @@ +["html", + ["p", + ["img", { + "src": "/url/", + "alt": "alt text", + "title": "title has spaces afterward" + } ] + ] +] diff --git a/node_modules/markdown/test/features/images/spaces_round_title.text b/node_modules/markdown/test/features/images/spaces_round_title.text new file mode 100644 index 00000000..03761e2e --- /dev/null +++ b/node_modules/markdown/test/features/images/spaces_round_title.text @@ -0,0 +1 @@ +![alt text](/url/ "title has spaces afterward" ) diff --git a/node_modules/markdown/test/features/images/title.json b/node_modules/markdown/test/features/images/title.json new file mode 100644 index 00000000..73e778b7 --- /dev/null +++ b/node_modules/markdown/test/features/images/title.json @@ -0,0 +1,9 @@ +["html", + ["p", + ["img", { + "src": "/path/to/img.jpg", + "alt": "Alt text", + "title": "Optional title" + } ] + ] +] diff --git a/node_modules/markdown/test/features/images/title.text b/node_modules/markdown/test/features/images/title.text new file mode 100644 index 00000000..85a35204 --- /dev/null +++ b/node_modules/markdown/test/features/images/title.text @@ -0,0 +1 @@ +![Alt text](/path/to/img.jpg "Optional title") diff --git a/node_modules/markdown/test/features/linebreaks/simple.json b/node_modules/markdown/test/features/linebreaks/simple.json new file mode 100644 index 00000000..30dacf13 --- /dev/null +++ b/node_modules/markdown/test/features/linebreaks/simple.json @@ -0,0 +1,7 @@ +["html", + ["p", + "The quick brown fox", + ["br"], + "jumps over the lazy dog." + ] +] diff --git a/node_modules/markdown/test/features/linebreaks/simple.text b/node_modules/markdown/test/features/linebreaks/simple.text new file mode 100644 index 00000000..c73db9c4 --- /dev/null +++ b/node_modules/markdown/test/features/linebreaks/simple.text @@ -0,0 +1,2 @@ +The quick brown fox +jumps over the lazy dog. diff --git a/node_modules/markdown/test/features/links/autolink_email.json b/node_modules/markdown/test/features/links/autolink_email.json new file mode 100644 index 00000000..863679d8 --- /dev/null +++ b/node_modules/markdown/test/features/links/autolink_email.json @@ -0,0 +1,10 @@ +["html", + ["p", + "Email addresses written like ", + ["a", + { "href" : "mailto:bill@microsoft.com" }, + "bill@microsoft.com" + ], + " get autolinkified." + ] +] diff --git a/node_modules/markdown/test/features/links/autolink_email.text b/node_modules/markdown/test/features/links/autolink_email.text new file mode 100644 index 00000000..7a3a5847 --- /dev/null +++ b/node_modules/markdown/test/features/links/autolink_email.text @@ -0,0 +1 @@ +Email addresses written like get autolinkified. diff --git a/node_modules/markdown/test/features/links/autolink_in_code.json b/node_modules/markdown/test/features/links/autolink_in_code.json new file mode 100644 index 00000000..234bb2a4 --- /dev/null +++ b/node_modules/markdown/test/features/links/autolink_in_code.json @@ -0,0 +1,8 @@ +["html", + ["p", + "Autolinks don't happen inside code: ", + ["code", + "" + ] + ] +] diff --git a/node_modules/markdown/test/features/links/autolink_in_code.text b/node_modules/markdown/test/features/links/autolink_in_code.text new file mode 100644 index 00000000..94b8e624 --- /dev/null +++ b/node_modules/markdown/test/features/links/autolink_in_code.text @@ -0,0 +1 @@ +Autolinks don't happen inside code: `` diff --git a/node_modules/markdown/test/features/links/autolink_url.json b/node_modules/markdown/test/features/links/autolink_url.json new file mode 100644 index 00000000..54158341 --- /dev/null +++ b/node_modules/markdown/test/features/links/autolink_url.json @@ -0,0 +1,10 @@ +["html", + ["p", + "URLs like ", + ["a", + { "href" : "http://google.com" }, + "http://google.com" + ], + " get autolinkified." + ] +] diff --git a/node_modules/markdown/test/features/links/autolink_url.text b/node_modules/markdown/test/features/links/autolink_url.text new file mode 100644 index 00000000..eda590b0 --- /dev/null +++ b/node_modules/markdown/test/features/links/autolink_url.text @@ -0,0 +1 @@ +URLs like get autolinkified. diff --git a/node_modules/markdown/test/features/links/case_insensitive.json b/node_modules/markdown/test/features/links/case_insensitive.json new file mode 100644 index 00000000..ba6c4d96 --- /dev/null +++ b/node_modules/markdown/test/features/links/case_insensitive.json @@ -0,0 +1,20 @@ +["html", + ["p", + "This is ", + ["a", + { "href" : "http://google.com" }, + "google" + ], + ". ", + ["a", + { "href" : "http://google.com" }, + "Google" + ], + " and ", + ["a", + { "href" : "http://google.com" }, + "this" + ], + " are the same thing too" + ] +] diff --git a/node_modules/markdown/test/features/links/case_insensitive.text b/node_modules/markdown/test/features/links/case_insensitive.text new file mode 100644 index 00000000..8fc74389 --- /dev/null +++ b/node_modules/markdown/test/features/links/case_insensitive.text @@ -0,0 +1,3 @@ +This is [google]. [Google] and [this][GoOgLe] are the same thing too + +[GOOGLE]: http://google.com diff --git a/node_modules/markdown/test/features/links/implicit.json b/node_modules/markdown/test/features/links/implicit.json new file mode 100644 index 00000000..d67a734a --- /dev/null +++ b/node_modules/markdown/test/features/links/implicit.json @@ -0,0 +1,15 @@ +["html", + ["p", + "These ", + ["a", + { "href" : "http://links.com" }, + "links" + ], + " use ", + ["a", + { "href" : "http://implicit.com" }, + "implicit" + ], + " references." + ] +] diff --git a/node_modules/markdown/test/features/links/implicit.text b/node_modules/markdown/test/features/links/implicit.text new file mode 100644 index 00000000..f66f2cbe --- /dev/null +++ b/node_modules/markdown/test/features/links/implicit.text @@ -0,0 +1,4 @@ +These [links][] use [implicit] references. + +[links]: http://links.com +[implicit]: http://implicit.com diff --git a/node_modules/markdown/test/features/links/inline.json b/node_modules/markdown/test/features/links/inline.json new file mode 100644 index 00000000..8ac50399 --- /dev/null +++ b/node_modules/markdown/test/features/links/inline.json @@ -0,0 +1,10 @@ +["html", + ["p", + "An ", + ["a", + { "href" : "http://inline.com" }, + "inline" + ], + " link." + ] +] diff --git a/node_modules/markdown/test/features/links/inline.text b/node_modules/markdown/test/features/links/inline.text new file mode 100644 index 00000000..d6bbc758 --- /dev/null +++ b/node_modules/markdown/test/features/links/inline.text @@ -0,0 +1 @@ +An [inline](http://inline.com) link. diff --git a/node_modules/markdown/test/features/links/inline_with_newline.json b/node_modules/markdown/test/features/links/inline_with_newline.json new file mode 100644 index 00000000..0c459d0a --- /dev/null +++ b/node_modules/markdown/test/features/links/inline_with_newline.json @@ -0,0 +1,10 @@ +["html", + ["p", + "An ", + ["a", + { "href" : "http://inline.com" }, + "inline\nlink" + ], + " with a newline." + ] +] diff --git a/node_modules/markdown/test/features/links/inline_with_newline.text b/node_modules/markdown/test/features/links/inline_with_newline.text new file mode 100644 index 00000000..3c170821 --- /dev/null +++ b/node_modules/markdown/test/features/links/inline_with_newline.text @@ -0,0 +1,2 @@ +An [inline +link](http://inline.com) with a newline. diff --git a/node_modules/markdown/test/features/links/inline_with_title.json b/node_modules/markdown/test/features/links/inline_with_title.json new file mode 100644 index 00000000..6d2d703a --- /dev/null +++ b/node_modules/markdown/test/features/links/inline_with_title.json @@ -0,0 +1,11 @@ +["html", + ["p", + "An ", + ["a", + { "href" : "http://inline.com", + "title" : "le title" }, + "inline link" + ], + " with a title." + ] +] diff --git a/node_modules/markdown/test/features/links/inline_with_title.text b/node_modules/markdown/test/features/links/inline_with_title.text new file mode 100644 index 00000000..5a2d66d4 --- /dev/null +++ b/node_modules/markdown/test/features/links/inline_with_title.text @@ -0,0 +1 @@ +An [inline link](http://inline.com "le title") with a title. diff --git a/node_modules/markdown/test/features/links/missing_references.json b/node_modules/markdown/test/features/links/missing_references.json new file mode 100644 index 00000000..3c0415a9 --- /dev/null +++ b/node_modules/markdown/test/features/links/missing_references.json @@ -0,0 +1,11 @@ +["html", + ["p", + "Link with [missing][id] reference" + ], + ["p", + "Link with [empty][] reference" + ], + ["p", + "Link with [inferred] reference" + ] +] diff --git a/node_modules/markdown/test/features/links/missing_references.text b/node_modules/markdown/test/features/links/missing_references.text new file mode 100644 index 00000000..3a170098 --- /dev/null +++ b/node_modules/markdown/test/features/links/missing_references.text @@ -0,0 +1,5 @@ +Link with [missing][id] reference + +Link with [empty][] reference + +Link with [inferred] reference diff --git a/node_modules/markdown/test/features/links/parens_escaped_inline.json b/node_modules/markdown/test/features/links/parens_escaped_inline.json new file mode 100644 index 00000000..62496ec9 --- /dev/null +++ b/node_modules/markdown/test/features/links/parens_escaped_inline.json @@ -0,0 +1,10 @@ +["html", + ["p", + ["a", + { "href": "/url(test)", + "title": "title" }, + "Inline link" + ], + " with escaped parens." + ], +] diff --git a/node_modules/markdown/test/features/links/parens_escaped_inline.text b/node_modules/markdown/test/features/links/parens_escaped_inline.text new file mode 100644 index 00000000..726f0205 --- /dev/null +++ b/node_modules/markdown/test/features/links/parens_escaped_inline.text @@ -0,0 +1 @@ +[Inline link](/url\(test\) "title") with escaped parens. diff --git a/node_modules/markdown/test/features/links/parens_inline.json b/node_modules/markdown/test/features/links/parens_inline.json new file mode 100644 index 00000000..55e01987 --- /dev/null +++ b/node_modules/markdown/test/features/links/parens_inline.json @@ -0,0 +1,10 @@ +["html", + ["p", + ["a", + { "href": "/url(test)", + "title": "title" }, + "Inline link" + ], + " with non-escaped parens." + ], +] diff --git a/node_modules/markdown/test/features/links/parens_inline.text b/node_modules/markdown/test/features/links/parens_inline.text new file mode 100644 index 00000000..5f56b892 --- /dev/null +++ b/node_modules/markdown/test/features/links/parens_inline.text @@ -0,0 +1 @@ +[Inline link](/url(test) "title") with non-escaped parens. diff --git a/node_modules/markdown/test/features/links/parens_reference.json b/node_modules/markdown/test/features/links/parens_reference.json new file mode 100644 index 00000000..525b96b4 --- /dev/null +++ b/node_modules/markdown/test/features/links/parens_reference.json @@ -0,0 +1,10 @@ +["html", + ["p", + ["a", + { "href": "/url(test)", + "title": "title" }, + "Reference link" + ], + " with non-escaped parens." + ], +] diff --git a/node_modules/markdown/test/features/links/parens_reference.text b/node_modules/markdown/test/features/links/parens_reference.text new file mode 100644 index 00000000..8456895e --- /dev/null +++ b/node_modules/markdown/test/features/links/parens_reference.text @@ -0,0 +1,3 @@ +[Reference link][1] with non-escaped parens. + +[1]: /url(test) "title" diff --git a/node_modules/markdown/test/features/links/ref_reuse.json b/node_modules/markdown/test/features/links/ref_reuse.json new file mode 100644 index 00000000..67c9cff0 --- /dev/null +++ b/node_modules/markdown/test/features/links/ref_reuse.json @@ -0,0 +1,14 @@ +["html", + ["p", + "Two ", + ["a", + { "href" : "http://google.com" }, + "links" + ], + ", one ", + ["a", + { "href" : "http://google.com" }, + "ref" + ] + ] +] diff --git a/node_modules/markdown/test/features/links/ref_reuse.text b/node_modules/markdown/test/features/links/ref_reuse.text new file mode 100644 index 00000000..5428cca2 --- /dev/null +++ b/node_modules/markdown/test/features/links/ref_reuse.text @@ -0,0 +1,3 @@ +Two [links][id], one [ref][id] + +[id]: http://google.com diff --git a/node_modules/markdown/test/features/links/reference.json b/node_modules/markdown/test/features/links/reference.json new file mode 100644 index 00000000..2876129f --- /dev/null +++ b/node_modules/markdown/test/features/links/reference.json @@ -0,0 +1,10 @@ +["html", + ["p", + "A ", + ["a", + { "href" : "http://reference.com" }, + "link using a reference" + ], + "." + ] +] diff --git a/node_modules/markdown/test/features/links/reference.text b/node_modules/markdown/test/features/links/reference.text new file mode 100644 index 00000000..ede662eb --- /dev/null +++ b/node_modules/markdown/test/features/links/reference.text @@ -0,0 +1,3 @@ +A [link using a reference][1]. + +[1]: http://reference.com diff --git a/node_modules/markdown/test/features/links/reference_with_space.json b/node_modules/markdown/test/features/links/reference_with_space.json new file mode 100644 index 00000000..09534f74 --- /dev/null +++ b/node_modules/markdown/test/features/links/reference_with_space.json @@ -0,0 +1,10 @@ +["html", + ["p", + "A ", + ["a", + { "href" : "http://reference.com" }, + "link using a reference" + ], + " separated by a space." + ] +] diff --git a/node_modules/markdown/test/features/links/reference_with_space.text b/node_modules/markdown/test/features/links/reference_with_space.text new file mode 100644 index 00000000..d1184c38 --- /dev/null +++ b/node_modules/markdown/test/features/links/reference_with_space.text @@ -0,0 +1,3 @@ +A [link using a reference] [1] separated by a space. + +[1]: http://reference.com diff --git a/node_modules/markdown/test/features/lists/bullet_types.json b/node_modules/markdown/test/features/lists/bullet_types.json new file mode 100644 index 00000000..b9161e06 --- /dev/null +++ b/node_modules/markdown/test/features/lists/bullet_types.json @@ -0,0 +1,26 @@ +["html", + ["p", + "Stars" + ], + ["ul", + ["li", + "star" + ] + ], + ["p", + "Dashes" + ], + ["ul", + ["li", + "dash" + ] + ], + ["p", + "Pluses" + ], + ["ul", + ["li", + "plus" + ] + ] +] diff --git a/node_modules/markdown/test/features/lists/bullet_types.text b/node_modules/markdown/test/features/lists/bullet_types.text new file mode 100644 index 00000000..2f152d66 --- /dev/null +++ b/node_modules/markdown/test/features/lists/bullet_types.text @@ -0,0 +1,11 @@ +Stars + +* star + +Dashes + +- dash + +Pluses + ++ plus diff --git a/node_modules/markdown/test/features/lists/hr_abutting.json b/node_modules/markdown/test/features/lists/hr_abutting.json new file mode 100644 index 00000000..db3fa1ba --- /dev/null +++ b/node_modules/markdown/test/features/lists/hr_abutting.json @@ -0,0 +1,9 @@ +["html", + ["ul", + [ "li", "foo" ], + [ "li", "bar" ], + ], + ["hr"], + ["p", "after"] +] + diff --git a/node_modules/markdown/test/features/lists/hr_abutting.text b/node_modules/markdown/test/features/lists/hr_abutting.text new file mode 100644 index 00000000..bafccd90 --- /dev/null +++ b/node_modules/markdown/test/features/lists/hr_abutting.text @@ -0,0 +1,6 @@ +* foo +* bar + + * * * +after + diff --git a/node_modules/markdown/test/features/lists/hr_inside.json b/node_modules/markdown/test/features/lists/hr_inside.json new file mode 100644 index 00000000..373ba003 --- /dev/null +++ b/node_modules/markdown/test/features/lists/hr_inside.json @@ -0,0 +1,10 @@ +["html", + ["ul", + [ "li", + ["p", "before"], + ["hr"], + ["p", "after"], + ] + ] +] + diff --git a/node_modules/markdown/test/features/lists/hr_inside.text b/node_modules/markdown/test/features/lists/hr_inside.text new file mode 100644 index 00000000..fb4b0198 --- /dev/null +++ b/node_modules/markdown/test/features/lists/hr_inside.text @@ -0,0 +1,5 @@ +* before + + - - - - + after + diff --git a/node_modules/markdown/test/features/lists/lazy_wrapping.json b/node_modules/markdown/test/features/lists/lazy_wrapping.json new file mode 100644 index 00000000..88021ec5 --- /dev/null +++ b/node_modules/markdown/test/features/lists/lazy_wrapping.json @@ -0,0 +1,10 @@ +["html", + ["ul", + ["li", + "If you're too\nlazy to wrap your" + ], + ["li", + "Lists nicely, this\nwill still work" + ] + ] +] diff --git a/node_modules/markdown/test/features/lists/lazy_wrapping.text b/node_modules/markdown/test/features/lists/lazy_wrapping.text new file mode 100644 index 00000000..dd05189f --- /dev/null +++ b/node_modules/markdown/test/features/lists/lazy_wrapping.text @@ -0,0 +1,4 @@ +* If you're too +lazy to wrap your +* Lists nicely, this +will still work diff --git a/node_modules/markdown/test/features/lists/leading_whitespace.json b/node_modules/markdown/test/features/lists/leading_whitespace.json new file mode 100644 index 00000000..a502e778 --- /dev/null +++ b/node_modules/markdown/test/features/lists/leading_whitespace.json @@ -0,0 +1,10 @@ +["html", + ["ul", + ["li", + "white" + ], + ["li", + "space" + ] + ] +] diff --git a/node_modules/markdown/test/features/lists/leading_whitespace.text b/node_modules/markdown/test/features/lists/leading_whitespace.text new file mode 100644 index 00000000..0b8e622c --- /dev/null +++ b/node_modules/markdown/test/features/lists/leading_whitespace.text @@ -0,0 +1,2 @@ + * white + * space diff --git a/node_modules/markdown/test/features/lists/loose.json b/node_modules/markdown/test/features/lists/loose.json new file mode 100644 index 00000000..a64cecc9 --- /dev/null +++ b/node_modules/markdown/test/features/lists/loose.json @@ -0,0 +1,22 @@ +["html", + ["ul", + ["li", + ["p", + "the quick brown fox jumps\nover the lazy dog" + ] + ], + ["li", + ["p", + "pack my box with five\ndozen liquor jugs" + ], + ["p", + "this item has a\nsecond paragraph" + ] + ], + ["li", + ["p", + "this item has\nonly one paragraph" + ] + ] + ] +] diff --git a/node_modules/markdown/test/features/lists/loose.text b/node_modules/markdown/test/features/lists/loose.text new file mode 100644 index 00000000..4ae8fa80 --- /dev/null +++ b/node_modules/markdown/test/features/lists/loose.text @@ -0,0 +1,11 @@ + * the quick brown fox jumps + over the lazy dog + + * pack my box with five + dozen liquor jugs + + this item has a + second paragraph + + * this item has + only one paragraph diff --git a/node_modules/markdown/test/features/lists/loose_with_inline.json b/node_modules/markdown/test/features/lists/loose_with_inline.json new file mode 100644 index 00000000..c0cbb7d0 --- /dev/null +++ b/node_modules/markdown/test/features/lists/loose_with_inline.json @@ -0,0 +1,36 @@ +["html", + ["ul", + ["li", + ["p", + "List item ", + ["em", + "ending" + ], + "\nwith ", + ["em", + "emphasis" + ], + "." + ] + ], + ["li", + ["p", + "List item\nwith ", + ["strong", + "strong emphasis" + ], + "." + ] + ], + ["li", + ["p", + "List item\nwith ", + ["a", + { "href" : "http://google.com" }, + "a link" + ], + "." + ] + ] + ] +] diff --git a/node_modules/markdown/test/features/lists/loose_with_inline.text b/node_modules/markdown/test/features/lists/loose_with_inline.text new file mode 100644 index 00000000..df532f64 --- /dev/null +++ b/node_modules/markdown/test/features/lists/loose_with_inline.text @@ -0,0 +1,8 @@ + * List item _ending_ + with _emphasis_. + + * List item + with **strong emphasis**. + + * List item + with [a link](http://google.com). diff --git a/node_modules/markdown/test/features/lists/multiline_inline.json b/node_modules/markdown/test/features/lists/multiline_inline.json new file mode 100644 index 00000000..21ec4761 --- /dev/null +++ b/node_modules/markdown/test/features/lists/multiline_inline.json @@ -0,0 +1,10 @@ +["html", + ["ul", + ["li", + "List items can have ", + [ "em", "inline content\nthat spans multiple lines" ], + ". Pain" + ] + ] +] + diff --git a/node_modules/markdown/test/features/lists/multiline_inline.text b/node_modules/markdown/test/features/lists/multiline_inline.text new file mode 100644 index 00000000..68dc2736 --- /dev/null +++ b/node_modules/markdown/test/features/lists/multiline_inline.text @@ -0,0 +1,2 @@ +* List items can have *inline content + that spans multiple lines*. Pain diff --git a/node_modules/markdown/test/features/lists/nested.json b/node_modules/markdown/test/features/lists/nested.json new file mode 100644 index 00000000..c88d1d38 --- /dev/null +++ b/node_modules/markdown/test/features/lists/nested.json @@ -0,0 +1,39 @@ +["html", + ["ol", + ["li", + "one", + ["ul", + ["li", + "alpha", + ["ul", + ["li", + "almond" + ], + ["li", + "brazil" + ] + ] + ], + ["li", + "beta", + ["ul", + ["li", + "cashew" + ] + ] + ] + ] + ], + ["li", + "two" + ], + ["li", + "three", + ["ul", + ["li", + "gamma" + ] + ] + ] + ] +] diff --git a/node_modules/markdown/test/features/lists/nested.text b/node_modules/markdown/test/features/lists/nested.text new file mode 100644 index 00000000..44f5a766 --- /dev/null +++ b/node_modules/markdown/test/features/lists/nested.text @@ -0,0 +1,9 @@ +1. one + * alpha + - almond + - brazil + * beta + - cashew +2. two +3. three + * gamma diff --git a/node_modules/markdown/test/features/lists/numeric.json b/node_modules/markdown/test/features/lists/numeric.json new file mode 100644 index 00000000..b696015d --- /dev/null +++ b/node_modules/markdown/test/features/lists/numeric.json @@ -0,0 +1,13 @@ +["html", + ["ol", + ["li", + "one" + ], + ["li", + "two" + ], + ["li", + "three" + ] + ] +] diff --git a/node_modules/markdown/test/features/lists/numeric.text b/node_modules/markdown/test/features/lists/numeric.text new file mode 100644 index 00000000..e55dd9ae --- /dev/null +++ b/node_modules/markdown/test/features/lists/numeric.text @@ -0,0 +1,3 @@ +1. one +2. two +3. three diff --git a/node_modules/markdown/test/features/lists/tight.json b/node_modules/markdown/test/features/lists/tight.json new file mode 100644 index 00000000..b548cf0f --- /dev/null +++ b/node_modules/markdown/test/features/lists/tight.json @@ -0,0 +1,13 @@ +["html", + ["ul", + ["li", + "alpha" + ], + ["li", + "beta" + ], + ["li", + "gamma" + ] + ] +] diff --git a/node_modules/markdown/test/features/lists/tight.text b/node_modules/markdown/test/features/lists/tight.text new file mode 100644 index 00000000..95887309 --- /dev/null +++ b/node_modules/markdown/test/features/lists/tight.text @@ -0,0 +1,3 @@ +* alpha +* beta +* gamma diff --git a/node_modules/markdown/test/features/meta/attribute.json b/node_modules/markdown/test/features/meta/attribute.json new file mode 100644 index 00000000..8ff7d202 --- /dev/null +++ b/node_modules/markdown/test/features/meta/attribute.json @@ -0,0 +1,6 @@ +["html", + ["p", + { "foo" : "bar" }, + "A paragraph with an\narbitrary attribute." + ] +] diff --git a/node_modules/markdown/test/features/meta/attribute.text b/node_modules/markdown/test/features/meta/attribute.text new file mode 100644 index 00000000..fd9d568f --- /dev/null +++ b/node_modules/markdown/test/features/meta/attribute.text @@ -0,0 +1,3 @@ +A paragraph with an +arbitrary attribute. +{: foo=bar} diff --git a/node_modules/markdown/test/features/meta/class.json b/node_modules/markdown/test/features/meta/class.json new file mode 100644 index 00000000..21a0013a --- /dev/null +++ b/node_modules/markdown/test/features/meta/class.json @@ -0,0 +1,6 @@ +["html", + ["p", + { "class" : "para" }, + "This is a paragraph\nwith an ID." + ] +] diff --git a/node_modules/markdown/test/features/meta/class.text b/node_modules/markdown/test/features/meta/class.text new file mode 100644 index 00000000..82ad4327 --- /dev/null +++ b/node_modules/markdown/test/features/meta/class.text @@ -0,0 +1,3 @@ +This is a paragraph +with an ID. +{: .para} diff --git a/node_modules/markdown/test/features/meta/code.json b/node_modules/markdown/test/features/meta/code.json new file mode 100644 index 00000000..6fc60af8 --- /dev/null +++ b/node_modules/markdown/test/features/meta/code.json @@ -0,0 +1,8 @@ +["html", + ["pre", + { "class" : "foo" }, + ["code", + "a code block;\n\nwith multiple lines;\n\nand a class;" + ] + ] +] diff --git a/node_modules/markdown/test/features/meta/code.text b/node_modules/markdown/test/features/meta/code.text new file mode 100644 index 00000000..a0c5b736 --- /dev/null +++ b/node_modules/markdown/test/features/meta/code.text @@ -0,0 +1,6 @@ + a code block; + + with multiple lines; + + and a class; +{: .foo} diff --git a/node_modules/markdown/test/features/meta/document.json b/node_modules/markdown/test/features/meta/document.json new file mode 100644 index 00000000..74d9e9c4 --- /dev/null +++ b/node_modules/markdown/test/features/meta/document.json @@ -0,0 +1,9 @@ +["html", + { + "key" : "value", + "anotherkey" : "another value" + }, + ["p", + "A regular paragraph" + ] +] diff --git a/node_modules/markdown/test/features/meta/document.text b/node_modules/markdown/test/features/meta/document.text new file mode 100644 index 00000000..553173a0 --- /dev/null +++ b/node_modules/markdown/test/features/meta/document.text @@ -0,0 +1,4 @@ +Key: value +AnotherKey: another value + +A regular paragraph diff --git a/node_modules/markdown/test/features/meta/id.json b/node_modules/markdown/test/features/meta/id.json new file mode 100644 index 00000000..ba9a79d9 --- /dev/null +++ b/node_modules/markdown/test/features/meta/id.json @@ -0,0 +1,6 @@ +["html", + ["p", + { "id" : "para" }, + "This is a paragraph\nwith an ID." + ] +] diff --git a/node_modules/markdown/test/features/meta/id.text b/node_modules/markdown/test/features/meta/id.text new file mode 100644 index 00000000..c392d659 --- /dev/null +++ b/node_modules/markdown/test/features/meta/id.text @@ -0,0 +1,3 @@ +This is a paragraph +with an ID. +{: #para} diff --git a/node_modules/markdown/test/features/meta/inline.json b/node_modules/markdown/test/features/meta/inline.json new file mode 100644 index 00000000..1a459c20 --- /dev/null +++ b/node_modules/markdown/test/features/meta/inline.json @@ -0,0 +1,15 @@ +["html", + ["p", + "An ", + ["em", + { "class" : "foo" }, + "em" + ], + " and ", + ["strong", + { "class" : "bar" }, + "strong" + ], + "\nwith attached attributes." + ] +] diff --git a/node_modules/markdown/test/features/meta/inline.text b/node_modules/markdown/test/features/meta/inline.text new file mode 100644 index 00000000..a84a5316 --- /dev/null +++ b/node_modules/markdown/test/features/meta/inline.text @@ -0,0 +1,2 @@ +An *em*{: .foo} and **strong**{: .bar} +with attached attributes. diff --git a/node_modules/markdown/test/features/meta/inner_whitespace.json b/node_modules/markdown/test/features/meta/inner_whitespace.json new file mode 100644 index 00000000..3c1c33c3 --- /dev/null +++ b/node_modules/markdown/test/features/meta/inner_whitespace.json @@ -0,0 +1,14 @@ +["html", + ["p", + { "id" : "none" }, + "We can have no whitespace" + ], + ["p", + { "id" : "one" }, + "Or a single whitespace" + ], + ["p", + { "id" : "lots" }, + "And even lots of whitespace" + ] +] diff --git a/node_modules/markdown/test/features/meta/inner_whitespace.text b/node_modules/markdown/test/features/meta/inner_whitespace.text new file mode 100644 index 00000000..e75b3c59 --- /dev/null +++ b/node_modules/markdown/test/features/meta/inner_whitespace.text @@ -0,0 +1,8 @@ +We can have no whitespace +{:#none} + +Or a single whitespace +{: #one } + +And even lots of whitespace +{: #lots } diff --git a/node_modules/markdown/test/features/meta/leading_whitespace.json b/node_modules/markdown/test/features/meta/leading_whitespace.json new file mode 100644 index 00000000..ac6c55ed --- /dev/null +++ b/node_modules/markdown/test/features/meta/leading_whitespace.json @@ -0,0 +1,21 @@ +["html", + ["p", + { "id" : "zero" }, + "Zero" + ], + ["p", + { "id" : "one" }, + "One" + ], + ["p", + { "id" : "two" }, + "Two" + ], + ["p", + { "id" : "three" }, + "Three" + ], + ["p", + "Four\n {: #four}" + ] +] diff --git a/node_modules/markdown/test/features/meta/leading_whitespace.text b/node_modules/markdown/test/features/meta/leading_whitespace.text new file mode 100644 index 00000000..99f4b033 --- /dev/null +++ b/node_modules/markdown/test/features/meta/leading_whitespace.text @@ -0,0 +1,14 @@ +Zero +{: #zero} + +One + {: #one} + +Two + {: #two} + +Three + {: #three} + +Four + {: #four} diff --git a/node_modules/markdown/test/features/meta/list.json b/node_modules/markdown/test/features/meta/list.json new file mode 100644 index 00000000..cf2da9e8 --- /dev/null +++ b/node_modules/markdown/test/features/meta/list.json @@ -0,0 +1,11 @@ +["html", + ["ul", + { "id" : "list" }, + ["li", + "here's a\nloose list" + ], + ["li", + "it might confuse the\nblock_meta routine" + ] + ] +] diff --git a/node_modules/markdown/test/features/meta/list.text b/node_modules/markdown/test/features/meta/list.text new file mode 100644 index 00000000..f0b0b3ed --- /dev/null +++ b/node_modules/markdown/test/features/meta/list.text @@ -0,0 +1,6 @@ + * here's a + loose list + + * it might confuse the + block_meta routine + {: #list} diff --git a/node_modules/markdown/test/features/meta/multiple_classes.json b/node_modules/markdown/test/features/meta/multiple_classes.json new file mode 100644 index 00000000..b9475a14 --- /dev/null +++ b/node_modules/markdown/test/features/meta/multiple_classes.json @@ -0,0 +1,11 @@ +["html", + ["p", + { "class" : "foo bar" }, + "Here's a paragraph and\nan ", + ["em", + { "class" : "foo bar" }, + "em" + ], + "\nwith multiple classes" + ] +] diff --git a/node_modules/markdown/test/features/meta/multiple_classes.text b/node_modules/markdown/test/features/meta/multiple_classes.text new file mode 100644 index 00000000..1d83b071 --- /dev/null +++ b/node_modules/markdown/test/features/meta/multiple_classes.text @@ -0,0 +1,4 @@ +Here's a paragraph and +an *em*{: .foo .bar} +with multiple classes +{: .foo .bar} diff --git a/node_modules/markdown/test/features/meta/quoted.json b/node_modules/markdown/test/features/meta/quoted.json new file mode 100644 index 00000000..bb108460 --- /dev/null +++ b/node_modules/markdown/test/features/meta/quoted.json @@ -0,0 +1,6 @@ +["html", + ["p", + { "foo" : "bar baz" }, + "A paragraph with a\nquoted attribute." + ] +] diff --git a/node_modules/markdown/test/features/meta/quoted.text b/node_modules/markdown/test/features/meta/quoted.text new file mode 100644 index 00000000..778e4034 --- /dev/null +++ b/node_modules/markdown/test/features/meta/quoted.text @@ -0,0 +1,3 @@ +A paragraph with a +quoted attribute. +{: foo="bar baz"} diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Amps_and_angle_encoding.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Amps_and_angle_encoding.json new file mode 100644 index 00000000..789f9165 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Amps_and_angle_encoding.json @@ -0,0 +1,22 @@ +["html", ["p", "AT&T has an ampersand in their name."], + ["p", "AT&T is another way to write it."], + ["p", "This & that."], + ["p", "4 < 5."], + ["p", "6 > 5."], + ["p", "Here's a ", ["a", { + "href": "http://example.com/?foo=1&bar=2" + }, + "link"], " with an ampersand in the URL."], + ["p", "Here's a link with an amersand in the link text: ", ["a", { + "href": "http://att.com/", + "title": "AT&T" + }, + "AT&T"], "."], + ["p", "Here's an inline ", ["a", { + "href": "/script?foo=1&bar=2" + }, + "link"], "."], + ["p", "Here's an inline ", ["a", { + "href": "/script?foo=1&bar=2" + }, + "link"], "."]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Amps_and_angle_encoding.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Amps_and_angle_encoding.text new file mode 100644 index 00000000..0e9527f9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Amps_and_angle_encoding.text @@ -0,0 +1,21 @@ +AT&T has an ampersand in their name. + +AT&T is another way to write it. + +This & that. + +4 < 5. + +6 > 5. + +Here's a [link] [1] with an ampersand in the URL. + +Here's a link with an amersand in the link text: [AT&T] [2]. + +Here's an inline [link](/script?foo=1&bar=2). + +Here's an inline [link](). + + +[1]: http://example.com/?foo=1&bar=2 +[2]: http://att.com/ "AT&T" \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Amps_and_angle_encoding.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Amps_and_angle_encoding.xhtml new file mode 100644 index 00000000..9606860b --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Amps_and_angle_encoding.xhtml @@ -0,0 +1,17 @@ +

    AT&T has an ampersand in their name.

    + +

    AT&T is another way to write it.

    + +

    This & that.

    + +

    4 < 5.

    + +

    6 > 5.

    + +

    Here's a link with an ampersand in the URL.

    + +

    Here's a link with an amersand in the link text: AT&T.

    + +

    Here's an inline link.

    + +

    Here's an inline link.

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Auto_links.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Auto_links.json new file mode 100644 index 00000000..0c92fc84 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Auto_links.json @@ -0,0 +1,20 @@ +["html", ["p", "Link: ", ["a", { + "href": "http://example.com/" +}, +"http://example.com/"], "."], + ["p", "With an ampersand: ", ["a", { + "href": "http://example.com/?foo=1&bar=2" + }, + "http://example.com/?foo=1&bar=2"]], + ["ul", ["li", "In a list?"], + ["li", ["a", { + "href": "http://example.com/" + }, + "http://example.com/"]], + ["li", "It should."]], + ["blockquote", ["p", "Blockquoted: ", ["a", { + "href": "http://example.com/" + }, + "http://example.com/"]]], + ["p", "Auto-links should not occur here: ", ["code", ""]], + ["pre", ["code", "or here: \u000a"]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Auto_links.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Auto_links.text new file mode 100644 index 00000000..abbc4886 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Auto_links.text @@ -0,0 +1,13 @@ +Link: . + +With an ampersand: + +* In a list? +* +* It should. + +> Blockquoted: + +Auto-links should not occur here: `` + + or here: \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Auto_links.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Auto_links.xhtml new file mode 100644 index 00000000..f8df9852 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Auto_links.xhtml @@ -0,0 +1,18 @@ +

    Link: http://example.com/.

    + +

    With an ampersand: http://example.com/?foo=1&bar=2

    + + + +
    +

    Blockquoted: http://example.com/

    +
    + +

    Auto-links should not occur here: <http://example.com/>

    + +
    or here: <http://example.com/>
    +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Backslash_escapes.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Backslash_escapes.json new file mode 100644 index 00000000..c6f479f7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Backslash_escapes.json @@ -0,0 +1,49 @@ +["html", ["p", "These should all get escaped:"], + ["p", "Backslash: \\"], + ["p", "Backtick: `"], + ["p", "Asterisk: *"], + ["p", "Underscore: _"], + ["p", "Left brace: {"], + ["p", "Right brace: }"], + ["p", "Left bracket: ["], + ["p", "Right bracket: ]"], + ["p", "Left paren: ("], + ["p", "Right paren: )"], + ["p", "Greater-than: >"], + ["p", "Hash: #"], + ["p", "Period: ."], + ["p", "Bang: !"], + ["p", "Plus: +"], + ["p", "Minus: -"], + ["p", "These should not, because they occur within a code block:"], + ["pre", ["code", "Backslash: \\\\\u000a\u000aBacktick: \\`\u000a\u000aAsterisk: \\*\u000a\u000aUnderscore: \\_\u000a\u000aLeft brace: \\{\u000a\u000aRight brace: \\}\u000a\u000aLeft bracket: \\[\u000a\u000aRight bracket: \\]\u000a\u000aLeft paren: \\(\u000a\u000aRight paren: \\)\u000a\u000aGreater-than: \\>\u000a\u000aHash: \\#\u000a\u000aPeriod: \\.\u000a\u000aBang: \\!\u000a\u000aPlus: \\+\u000a\u000aMinus: \\-\u000a"]], + ["p", "Nor should these, which occur in code spans:"], + ["p", "Backslash: ", ["code", "\\\\"]], + ["p", "Backtick: ", ["code", "\\`"]], + ["p", "Asterisk: ", ["code", "\\*"]], + ["p", "Underscore: ", ["code", "\\_"]], + ["p", "Left brace: ", ["code", "\\{"]], + ["p", "Right brace: ", ["code", "\\}"]], + ["p", "Left bracket: ", ["code", "\\["]], + ["p", "Right bracket: ", ["code", "\\]"]], + ["p", "Left paren: ", ["code", "\\("]], + ["p", "Right paren: ", ["code", "\\)"]], + ["p", "Greater-than: ", ["code", "\\>"]], + ["p", "Hash: ", ["code", "\\#"]], + ["p", "Period: ", ["code", "\\."]], + ["p", "Bang: ", ["code", "\\!"]], + ["p", "Plus: ", ["code", "\\+"]], + ["p", "Minus: ", ["code", "\\-"]], + ["p", "These should get escaped, even though they're matching pairs for\u000aother Markdown constructs:"], + ["p", "*asterisks*"], + ["p", "_underscores_"], + ["p", "`backticks`"], + ["p", "This is a code span with a literal backslash-backtick sequence: ", ["code", "\\`"]], + ["p", "This is a tag with unescaped backticks ", ["span", { + "attr": "`ticks`" + }, + "bar"], "."], + ["p", "This is a tag with backslashes ", ["span", { + "attr": "\\\\backslashes\\\\" + }, + "bar"], "."]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Backslash_escapes.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Backslash_escapes.text new file mode 100644 index 00000000..5b014cb3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Backslash_escapes.text @@ -0,0 +1,120 @@ +These should all get escaped: + +Backslash: \\ + +Backtick: \` + +Asterisk: \* + +Underscore: \_ + +Left brace: \{ + +Right brace: \} + +Left bracket: \[ + +Right bracket: \] + +Left paren: \( + +Right paren: \) + +Greater-than: \> + +Hash: \# + +Period: \. + +Bang: \! + +Plus: \+ + +Minus: \- + + + +These should not, because they occur within a code block: + + Backslash: \\ + + Backtick: \` + + Asterisk: \* + + Underscore: \_ + + Left brace: \{ + + Right brace: \} + + Left bracket: \[ + + Right bracket: \] + + Left paren: \( + + Right paren: \) + + Greater-than: \> + + Hash: \# + + Period: \. + + Bang: \! + + Plus: \+ + + Minus: \- + + +Nor should these, which occur in code spans: + +Backslash: `\\` + +Backtick: `` \` `` + +Asterisk: `\*` + +Underscore: `\_` + +Left brace: `\{` + +Right brace: `\}` + +Left bracket: `\[` + +Right bracket: `\]` + +Left paren: `\(` + +Right paren: `\)` + +Greater-than: `\>` + +Hash: `\#` + +Period: `\.` + +Bang: `\!` + +Plus: `\+` + +Minus: `\-` + + +These should get escaped, even though they're matching pairs for +other Markdown constructs: + +\*asterisks\* + +\_underscores\_ + +\`backticks\` + +This is a code span with a literal backslash-backtick sequence: `` \` `` + +This is a tag with unescaped backticks bar. + +This is a tag with backslashes bar. diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Backslash_escapes.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Backslash_escapes.xhtml new file mode 100644 index 00000000..29870dac --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Backslash_escapes.xhtml @@ -0,0 +1,118 @@ +

    These should all get escaped:

    + +

    Backslash: \

    + +

    Backtick: `

    + +

    Asterisk: *

    + +

    Underscore: _

    + +

    Left brace: {

    + +

    Right brace: }

    + +

    Left bracket: [

    + +

    Right bracket: ]

    + +

    Left paren: (

    + +

    Right paren: )

    + +

    Greater-than: >

    + +

    Hash: #

    + +

    Period: .

    + +

    Bang: !

    + +

    Plus: +

    + +

    Minus: -

    + +

    These should not, because they occur within a code block:

    + +
    Backslash: \\
    +
    +Backtick: \`
    +
    +Asterisk: \*
    +
    +Underscore: \_
    +
    +Left brace: \{
    +
    +Right brace: \}
    +
    +Left bracket: \[
    +
    +Right bracket: \]
    +
    +Left paren: \(
    +
    +Right paren: \)
    +
    +Greater-than: \>
    +
    +Hash: \#
    +
    +Period: \.
    +
    +Bang: \!
    +
    +Plus: \+
    +
    +Minus: \-
    +
    + +

    Nor should these, which occur in code spans:

    + +

    Backslash: \\

    + +

    Backtick: \`

    + +

    Asterisk: \*

    + +

    Underscore: \_

    + +

    Left brace: \{

    + +

    Right brace: \}

    + +

    Left bracket: \[

    + +

    Right bracket: \]

    + +

    Left paren: \(

    + +

    Right paren: \)

    + +

    Greater-than: \>

    + +

    Hash: \#

    + +

    Period: \.

    + +

    Bang: \!

    + +

    Plus: \+

    + +

    Minus: \-

    + + +

    These should get escaped, even though they're matching pairs for +other Markdown constructs:

    + +

    *asterisks*

    + +

    _underscores_

    + +

    `backticks`

    + +

    This is a code span with a literal backslash-backtick sequence: \`

    + +

    This is a tag with unescaped backticks bar.

    + +

    This is a tag with backslashes bar.

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Blockquotes_with_code_blocks.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Blockquotes_with_code_blocks.json new file mode 100644 index 00000000..48411076 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Blockquotes_with_code_blocks.json @@ -0,0 +1,4 @@ +["html", ["blockquote", ["p", "Example:"], + ["pre", ["code", "sub status {\u000a print \"working\";\u000a}\u000a"]], + ["p", "Or:"], + ["pre", ["code", "sub status {\u000a return \"working\";\u000a}\u000a"]]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Blockquotes_with_code_blocks.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Blockquotes_with_code_blocks.text new file mode 100644 index 00000000..c31d1710 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Blockquotes_with_code_blocks.text @@ -0,0 +1,11 @@ +> Example: +> +> sub status { +> print "working"; +> } +> +> Or: +> +> sub status { +> return "working"; +> } diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Blockquotes_with_code_blocks.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Blockquotes_with_code_blocks.xhtml new file mode 100644 index 00000000..990202a1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Blockquotes_with_code_blocks.xhtml @@ -0,0 +1,15 @@ +
    +

    Example:

    + +
    sub status {
    +    print "working";
    +}
    +
    + +

    Or:

    + +
    sub status {
    +    return "working";
    +}
    +
    +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Blocks.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Blocks.json new file mode 100644 index 00000000..c8f62d73 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Blocks.json @@ -0,0 +1,7 @@ +["html", ["pre", ["code", "code block on the first line\u000a"]], + ["p", "Regular text."], + ["pre", ["code", "code block indented by spaces\u000a"]], + ["p", "Regular text."], + ["pre", ["code", "the lines in this block \u000aall contain trailing spaces \u000a"]], + ["p", "Regular Text."], + ["pre", ["code", "code block on the last line\u000a"]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Blocks.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Blocks.text new file mode 100644 index 00000000..b54b0928 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Blocks.text @@ -0,0 +1,14 @@ + code block on the first line + +Regular text. + + code block indented by spaces + +Regular text. + + the lines in this block + all contain trailing spaces + +Regular Text. + + code block on the last line \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Blocks.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Blocks.xhtml new file mode 100644 index 00000000..32703f5c --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Blocks.xhtml @@ -0,0 +1,18 @@ +
    code block on the first line
    +
    + +

    Regular text.

    + +
    code block indented by spaces
    +
    + +

    Regular text.

    + +
    the lines in this block  
    +all contain trailing spaces  
    +
    + +

    Regular Text.

    + +
    code block on the last line
    +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Spans.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Spans.json new file mode 100644 index 00000000..78b68408 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Spans.json @@ -0,0 +1,6 @@ +["html", ["p", ["code", ""]], + ["p", "Fix for backticks within HTML tag: ", ["span", { + "attr": "`ticks`" + }, + "like this"]], + ["p", "Here's how you put ", ["code", "`backticks`"], " in a code span."]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Spans.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Spans.text new file mode 100644 index 00000000..5c229c7a --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Spans.text @@ -0,0 +1,5 @@ +`` + +Fix for backticks within HTML tag: like this + +Here's how you put `` `backticks` `` in a code span. \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Spans.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Spans.xhtml new file mode 100644 index 00000000..b057457d --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Code_Spans.xhtml @@ -0,0 +1,5 @@ +

    <test a=" content of attribute ">

    + +

    Fix for backticks within HTML tag: like this

    + +

    Here's how you put `backticks` in a code span.

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Hard-wrapped_paragraphs_with_list-like_lines.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Hard-wrapped_paragraphs_with_list-like_lines.json new file mode 100644 index 00000000..09cd53b8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Hard-wrapped_paragraphs_with_list-like_lines.json @@ -0,0 +1,2 @@ +["html", ["p", "In Markdown 1.0.0 and earlier. Version\u000a8. This line turns into a list item.\u000aBecause a hard-wrapped line in the\u000amiddle of a paragraph looked like a\u000alist item."], + ["p", "Here's one with a bullet.\u000a* criminey."]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Hard-wrapped_paragraphs_with_list-like_lines.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Hard-wrapped_paragraphs_with_list-like_lines.text new file mode 100644 index 00000000..f8a5b27b --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Hard-wrapped_paragraphs_with_list-like_lines.text @@ -0,0 +1,8 @@ +In Markdown 1.0.0 and earlier. Version +8. This line turns into a list item. +Because a hard-wrapped line in the +middle of a paragraph looked like a +list item. + +Here's one with a bullet. +* criminey. diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Hard-wrapped_paragraphs_with_list-like_lines.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Hard-wrapped_paragraphs_with_list-like_lines.xhtml new file mode 100644 index 00000000..e21ac79a --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Hard-wrapped_paragraphs_with_list-like_lines.xhtml @@ -0,0 +1,8 @@ +

    In Markdown 1.0.0 and earlier. Version +8. This line turns into a list item. +Because a hard-wrapped line in the +middle of a paragraph looked like a +list item.

    + +

    Here's one with a bullet. +* criminey.

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Horizontal_rules.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Horizontal_rules.json new file mode 100644 index 00000000..be4b070a --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Horizontal_rules.json @@ -0,0 +1,3 @@ +["html", ["p", "Dashes:"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["pre", ["code", "---\u000a"]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["pre", ["code", "- - -\u000a"]], + ["p", "Asterisks:"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["pre", ["code", "***\u000a"]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["pre", ["code", "* * *\u000a"]], + ["p", "Underscores:"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["pre", ["code", "___\u000a"]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["pre", ["code", "_ _ _\u000a"]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Horizontal_rules.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Horizontal_rules.text new file mode 100644 index 00000000..1594bda2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Horizontal_rules.text @@ -0,0 +1,67 @@ +Dashes: + +--- + + --- + + --- + + --- + + --- + +- - - + + - - - + + - - - + + - - - + + - - - + + +Asterisks: + +*** + + *** + + *** + + *** + + *** + +* * * + + * * * + + * * * + + * * * + + * * * + + +Underscores: + +___ + + ___ + + ___ + + ___ + + ___ + +_ _ _ + + _ _ _ + + _ _ _ + + _ _ _ + + _ _ _ diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Horizontal_rules.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Horizontal_rules.xhtml new file mode 100644 index 00000000..2dc2ab65 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Horizontal_rules.xhtml @@ -0,0 +1,71 @@ +

    Dashes:

    + +
    + +
    + +
    + +
    + +
    ---
    +
    + +
    + +
    + +
    + +
    + +
    - - -
    +
    + +

    Asterisks:

    + +
    + +
    + +
    + +
    + +
    ***
    +
    + +
    + +
    + +
    + +
    + +
    * * *
    +
    + +

    Underscores:

    + +
    + +
    + +
    + +
    + +
    ___
    +
    + +
    + +
    + +
    + +
    + +
    _ _ _
    +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Images.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Images.json new file mode 100644 index 00000000..518f9d5e --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Images.json @@ -0,0 +1,48 @@ +["html", ["p", ["img", { + "src": "/path/to/img.jpg", + "alt": "Alt text" +}]], + ["p", ["img", { + "src": "/path/to/img.jpg", + "alt": "Alt text", + "title": "Optional title" + }]], + ["p", "Inline within a paragraph: ", ["a", { + "href": "/url/" + }, + "alt text"], "."], + ["p", ["img", { + "src": "/url/", + "alt": "alt text", + "title": "title preceded by two spaces" + }]], + ["p", ["img", { + "src": "/url/", + "alt": "alt text", + "title": "title has spaces afterward" + }]], + ["p", ["img", { + "src": "/url/", + "alt": "alt text" + }]], + ["p", ["img", { + "src": "/url/", + "alt": "alt text", + "title": "with a title" + }], "."], + ["p", ["img", { + "alt": "Empty" + }]], + ["p", ["img", { + "src": "http://example.com/(parens).jpg", + "alt": "this is a stupid URL" + }]], + ["p", ["img", { + "src": "/url/", + "alt": "alt text" + }]], + ["p", ["img", { + "src": "/url/", + "alt": "alt text", + "title": "Title here" + }]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Images.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Images.text new file mode 100644 index 00000000..57075909 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Images.text @@ -0,0 +1,26 @@ +![Alt text](/path/to/img.jpg) + +![Alt text](/path/to/img.jpg "Optional title") + +Inline within a paragraph: [alt text](/url/). + +![alt text](/url/ "title preceded by two spaces") + +![alt text](/url/ "title has spaces afterward" ) + +![alt text]() + +![alt text]( "with a title"). + +![Empty]() + +![this is a stupid URL](http://example.com/(parens).jpg) + + +![alt text][foo] + + [foo]: /url/ + +![alt text][bar] + + [bar]: /url/ "Title here" \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Images.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Images.xhtml new file mode 100644 index 00000000..925bc147 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Images.xhtml @@ -0,0 +1,21 @@ +

    Alt text

    + +

    Alt text

    + +

    Inline within a paragraph: alt text.

    + +

    alt text

    + +

    alt text

    + +

    alt text

    + +

    alt text.

    + +

    Empty

    + +

    this is a stupid URL

    + +

    alt text

    + +

    alt text

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Advanced).json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Advanced).json new file mode 100644 index 00000000..b865a878 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Advanced).json @@ -0,0 +1,11 @@ +["html", ["p", "Simple block on one line:"], "\u000a\u000a", ["div", "foo"], "\u000a\u000a", ["p", "And nested without indentation:"], "\u000a\u000a", ["div", "\u000a", ["div", "\u000a", ["div", "\u000afoo\u000a"], "\u000a", ["div", { + "style": ">" +}], "\u000a"], "\u000a", ["div", "bar"], "\u000a"], "\u000a\u000a", ["p", "And with attributes:"], "\u000a\u000a", ["div", "\u000a ", ["div", { + "id": "foo" +}], "\u000a"], "\u000a\u000a", ["p", "This was broken in 1.0.2b7:"], "\u000a\u000a", ["div", { + "class": "inlinepage" +}, +"\u000a", ["div", { + "class": "toggleableend" +}, +"\u000afoo\u000a"], "\u000a"], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Advanced).text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Advanced).text new file mode 100644 index 00000000..3633f813 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Advanced).text @@ -0,0 +1,30 @@ +Simple block on one line: + +
    foo
    + +And nested without indentation: + +
    +
    +
    +foo +
    +
    +
    +
    bar
    +
    + +And with attributes: + +
    +
    +
    +
    + +This was broken in 1.0.2b7: + +
    +
    +foo +
    +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Advanced).xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Advanced).xhtml new file mode 100644 index 00000000..884f14c1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Advanced).xhtml @@ -0,0 +1,30 @@ +

    Simple block on one line:

    + +
    foo
    + +

    And nested without indentation:

    + +
    +
    +
    +foo +
    +
    +
    +
    bar
    +
    + +

    And with attributes:

    + +
    +
    +
    +
    + +

    This was broken in 1.0.2b7:

    + +
    +
    +foo +
    +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).html b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).html new file mode 100644 index 00000000..6bf78f8f --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).html @@ -0,0 +1,72 @@ +

    Here's a simple block:

    + +
    + foo +
    + +

    This should be a code block, though:

    + +
    <div>
    +    foo
    +</div>
    +
    + +

    As should this:

    + +
    <div>foo</div>
    +
    + +

    Now, nested:

    + +
    +
    +
    + foo +
    +
    +
    + +

    This should just be an HTML comment:

    + + + +

    Multiline:

    + + + +

    Code block:

    + +
    <!-- Comment -->
    +
    + +

    Just plain comment, with trailing spaces on the line:

    + + + +

    Code:

    + +
    <hr />
    +
    + +

    Hr's:

    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).json new file mode 100644 index 00000000..3ea76f8c --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).json @@ -0,0 +1,18 @@ +["html", ["p", "Here's a simple block:"], "\u000a\u000a", ["div", "\u000a foo\u000a"], "\u000a\u000a", ["p", "This should be a code block, though:"], + ["pre", ["code", "
    \u000a foo\u000a
    \u000a"]], + ["p", "As should this:"], + ["pre", ["code", "
    foo
    \u000a"]], + ["p", "Now, nested:"], "\u000a\u000a", ["div", "\u000a ", ["div", "\u000a ", ["div", "\u000a foo\u000a "], "\u000a "], "\u000a"], "\u000a\u000a", ["p", "This should just be an HTML comment:"], "\u000a\u000a", "\u000a\u000a", ["p", "Multiline:"], "\u000a\u000a", "\u000a\u000a", ["p", "Code block:"], + ["pre", ["code", "\u000a"]], + ["p", "Just plain comment, with trailing spaces on the line:"], "\u000a\u000a", " \u000a\u000a", ["p", "Code:"], + ["pre", ["code", "
    \u000a"]], + ["p", "Hr's:"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], " \u000a\u000a", ["hr"], " \u000a\u000a", ["hr"], " \u000a\u000a", ["hr", { + "class": "foo", + "id": "bar" +}], "\u000a\u000a", ["hr", { + "class": "foo", + "id": "bar" +}], "\u000a\u000a", ["hr", { + "class": "foo", + "id": "bar" +}], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).text new file mode 100644 index 00000000..14aa2dc2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).text @@ -0,0 +1,69 @@ +Here's a simple block: + +
    + foo +
    + +This should be a code block, though: + +
    + foo +
    + +As should this: + +
    foo
    + +Now, nested: + +
    +
    +
    + foo +
    +
    +
    + +This should just be an HTML comment: + + + +Multiline: + + + +Code block: + + + +Just plain comment, with trailing spaces on the line: + + + +Code: + +
    + +Hr's: + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.html b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.html new file mode 100644 index 00000000..3f167a16 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.html @@ -0,0 +1,13 @@ +

    Paragraph one.

    + + + + + +

    Paragraph two.

    + + + +

    The end.

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.json new file mode 100644 index 00000000..7b0e9aee --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.json @@ -0,0 +1 @@ +["html", ["p", "Paragraph one."], "\u000a\u000a", "\u000a\u000a", "\u000a\u000a", ["p", "Paragraph two."], "\u000a\u000a", "\u000a\u000a", ["p", "The end."]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.text new file mode 100644 index 00000000..41d830d0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.text @@ -0,0 +1,13 @@ +Paragraph one. + + + + + +Paragraph two. + + + +The end. diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_inline_style.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_inline_style.json new file mode 100644 index 00000000..ba39d800 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_inline_style.json @@ -0,0 +1,52 @@ +["html", ["p", "Just a ", ["a", { + "href": "/url/" +}, +"URL"], "."], + ["p", ["a", { + "href": "/url/", + "title": "title" + }, + "URL and title"], "."], + ["p", ["a", { + "href": "/url/", + "title": "title preceded by two spaces" + }, + "URL and title"], "."], + ["p", ["a", { + "href": "/url/", + "title": "title preceded by a tab" + }, + "URL and title"], "."], + ["p", ["a", { + "href": "/url/", + "title": "title has spaces afterward" + }, + "URL and title"], "."], + ["p", ["a", { + "href": "/url/" + }, + "URL wrapped in angle brackets"], "."], + ["p", ["a", { + "href": "/url/", + "title": "Here's the title" + }, + "URL w/ angle brackets + title"], "."], + ["p", ["a", "Empty"], "."], + ["p", ["a", { + "href": "http://en.wikipedia.org/wiki/WIMP_(computing)" + }, + "With parens in the URL"]], + ["p", "(With outer parens and ", ["a", { + "href": "/foo(bar)" + }, + "parens in url"], ")"], + ["p", ["a", { + "href": "/foo(bar)", + "title": "and a title" + }, + "With parens in the URL"]], + ["p", "(With outer parens and ", ["a", { + "href": "/foo(bar)", + "title": "and a title" + }, + "parens in url"], ")"]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_inline_style.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_inline_style.text new file mode 100644 index 00000000..aba96583 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_inline_style.text @@ -0,0 +1,24 @@ +Just a [URL](/url/). + +[URL and title](/url/ "title"). + +[URL and title](/url/ "title preceded by two spaces"). + +[URL and title](/url/ "title preceded by a tab"). + +[URL and title](/url/ "title has spaces afterward" ). + +[URL wrapped in angle brackets](). + +[URL w/ angle brackets + title]( "Here's the title"). + +[Empty](). + +[With parens in the URL](http://en.wikipedia.org/wiki/WIMP_(computing)) + +(With outer parens and [parens in url](/foo(bar))) + + +[With parens in the URL](/foo(bar) "and a title") + +(With outer parens and [parens in url](/foo(bar) "and a title")) diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_inline_style.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_inline_style.xhtml new file mode 100644 index 00000000..9f351ef5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_inline_style.xhtml @@ -0,0 +1,23 @@ +

    Just a URL.

    + +

    URL and title.

    + +

    URL and title.

    + +

    URL and title.

    + +

    URL and title.

    + +

    URL wrapped in angle brackets.

    + +

    URL w/ angle brackets + title.

    + +

    Empty.

    + +

    With parens in the URL

    + +

    (With outer parens and parens in url)

    + +

    With parens in the URL

    + +

    (With outer parens and parens in url)

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_reference_style.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_reference_style.json new file mode 100644 index 00000000..0621b21c --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_reference_style.json @@ -0,0 +1,75 @@ +["html", ["p", "Foo ", ["a", { + "href": "/url/", + "title": "Title" +}, +"bar"], "."], + ["p", "Foo ", ["a", { + "href": "/url/", + "title": "Title" + }, + "bar"], "."], + ["p", "Foo ", ["a", { + "href": "/url/", + "title": "Title" + }, + "bar"], "."], + ["p", "With ", ["a", { + "href": "/url/" + }, + "embedded [brackets]"], "."], + ["p", "Indented ", ["a", { + "href": "/url" + }, + "once"], "."], + ["p", "Indented ", ["a", { + "href": "/url" + }, + "twice"], "."], + ["p", "Indented ", ["a", { + "href": "/url" + }, + "thrice"], "."], + ["p", "Indented [four][] times."], + ["pre", ["code", "[four]: /url\u000a"]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", ["a", { + "href": "foo" +}, +"this"], " should work"], + ["p", "So should ", ["a", { + "href": "foo" + }, + "this"], "."], + ["p", "And ", ["a", { + "href": "foo" + }, + "this"], "."], + ["p", "And ", ["a", { + "href": "foo" + }, + "this"], "."], + ["p", "And ", ["a", { + "href": "foo" + }, + "this"], "."], + ["p", "But not [that] []."], + ["p", "Nor [that][]."], + ["p", "Nor [that]."], + ["p", "[Something in brackets like ", ["a", { + "href": "foo" + }, + "this"], " should work]"], + ["p", "[Same with ", ["a", { + "href": "foo" + }, + "this"], ".]"], + ["p", "In this case, ", ["a", { + "href": "/somethingelse/" + }, + "this"], " points to something else."], + ["p", "Backslashing should suppress [this] and [this]."], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", "Here's one where the ", ["a", { + "href": "/url/" +}, +"link\u000abreaks"], " across lines."], + ["p", "Here's another where the ", ["a", { + "href": "/url/" + }, + "link \u000abreaks"], " across lines, but with a line-ending space."]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_reference_style.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_reference_style.text new file mode 100644 index 00000000..341ec88e --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_reference_style.text @@ -0,0 +1,71 @@ +Foo [bar] [1]. + +Foo [bar][1]. + +Foo [bar] +[1]. + +[1]: /url/ "Title" + + +With [embedded [brackets]] [b]. + + +Indented [once][]. + +Indented [twice][]. + +Indented [thrice][]. + +Indented [four][] times. + + [once]: /url + + [twice]: /url + + [thrice]: /url + + [four]: /url + + +[b]: /url/ + +* * * + +[this] [this] should work + +So should [this][this]. + +And [this] []. + +And [this][]. + +And [this]. + +But not [that] []. + +Nor [that][]. + +Nor [that]. + +[Something in brackets like [this][] should work] + +[Same with [this].] + +In this case, [this](/somethingelse/) points to something else. + +Backslashing should suppress \[this] and [this\]. + +[this]: foo + + +* * * + +Here's one where the [link +breaks] across lines. + +Here's another where the [link +breaks] across lines, but with a line-ending space. + + +[link breaks]: /url/ diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_reference_style.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_reference_style.xhtml new file mode 100644 index 00000000..8e70c32f --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_reference_style.xhtml @@ -0,0 +1,52 @@ +

    Foo bar.

    + +

    Foo bar.

    + +

    Foo bar.

    + +

    With embedded [brackets].

    + +

    Indented once.

    + +

    Indented twice.

    + +

    Indented thrice.

    + +

    Indented [four][] times.

    + +
    [four]: /url
    +
    + +
    + +

    this should work

    + +

    So should this.

    + +

    And this.

    + +

    And this.

    + +

    And this.

    + +

    But not [that] [].

    + +

    Nor [that][].

    + +

    Nor [that].

    + +

    [Something in brackets like this should work]

    + +

    [Same with this.]

    + +

    In this case, this points to something else.

    + +

    Backslashing should suppress [this] and [this].

    + +
    + +

    Here's one where the link +breaks across lines.

    + +

    Here's another where the link +breaks across lines, but with a line-ending space.

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_shortcut_references.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_shortcut_references.json new file mode 100644 index 00000000..8074216e --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_shortcut_references.json @@ -0,0 +1,19 @@ +["html", ["p", "This is the ", ["a", { + "href": "/simple" +}, +"simple case"], "."], + ["p", "This one has a ", ["a", { + "href": "/foo" + }, + "line\u000abreak"], "."], + ["p", "This one has a ", ["a", { + "href": "/foo" + }, + "line \u000abreak"], " with a line-ending space."], + ["p", ["a", { + "href": "/that" + }, + "this"], " and the ", ["a", { + "href": "/other" + }, + "other"]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_shortcut_references.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_shortcut_references.text new file mode 100644 index 00000000..8c44c98f --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_shortcut_references.text @@ -0,0 +1,20 @@ +This is the [simple case]. + +[simple case]: /simple + + + +This one has a [line +break]. + +This one has a [line +break] with a line-ending space. + +[line break]: /foo + + +[this] [that] and the [other] + +[this]: /this +[that]: /that +[other]: /other diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_shortcut_references.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_shortcut_references.xhtml new file mode 100644 index 00000000..bf81e939 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Links_shortcut_references.xhtml @@ -0,0 +1,9 @@ +

    This is the simple case.

    + +

    This one has a line +break.

    + +

    This one has a line +break with a line-ending space.

    + +

    this and the other

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Literal_quotes_in_titles.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Literal_quotes_in_titles.json new file mode 100644 index 00000000..05e28023 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Literal_quotes_in_titles.json @@ -0,0 +1,10 @@ +["html", ["p", "Foo ", ["a", { + "href": "/url/", + "title": "Title with \"quotes\" inside" +}, +"bar"], "."], + ["p", "Foo ", ["a", { + "href": "/url/", + "title": "Title with \"quotes\" inside" + }, + "bar"], "."]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Literal_quotes_in_titles.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Literal_quotes_in_titles.text new file mode 100644 index 00000000..29d0e423 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Literal_quotes_in_titles.text @@ -0,0 +1,7 @@ +Foo [bar][]. + +Foo [bar](/url/ "Title with "quotes" inside"). + + + [bar]: /url/ "Title with "quotes" inside" + diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Literal_quotes_in_titles.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Literal_quotes_in_titles.xhtml new file mode 100644 index 00000000..611c1ac6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Literal_quotes_in_titles.xhtml @@ -0,0 +1,3 @@ +

    Foo bar.

    + +

    Foo bar.

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Basics.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Basics.json new file mode 100644 index 00000000..38c2f80b --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Basics.json @@ -0,0 +1,96 @@ +["html", ["h1", "Markdown: Basics"], "\u000a\u000a", ["ul", { + "id": "ProjectSubmenu" +}, +["li", ["a", { + "href": "/projects/markdown/", + "title": "Markdown Project Page" +}, +"Main"]], + ["li", ["a", { + "class": "selected", + "title": "Markdown Basics" + }, + "Basics"]], + ["li", ["a", { + "href": "/projects/markdown/syntax", + "title": "Markdown Syntax Documentation" + }, + "Syntax"]], + ["li", ["a", { + "href": "/projects/markdown/license", + "title": "Pricing and License Information" + }, + "License"]], + ["li", ["a", { + "href": "/projects/markdown/dingus", + "title": "Online Markdown Web Form" + }, + "Dingus"]]], "\u000a\u000a", ["h2", "Getting the Gist of Markdown's Formatting Syntax"], "\u000a\u000a", ["p", "This page offers a brief overview of what it's like to use Markdown.\u000aThe ", ["a", { + "href": "/projects/markdown/syntax", + "title": "Markdown Syntax" +}, +"syntax page"], " provides complete, detailed documentation for\u000aevery feature, but Markdown should be very easy to pick up simply by\u000alooking at a few examples of it in action. The examples on this page\u000aare written in a before/after style, showing example syntax and the\u000aHTML output produced by Markdown."], + ["p", "It's also helpful to simply try Markdown out; the ", ["a", { + "href": "/projects/markdown/dingus", + "title": "Markdown Dingus" + }, + "Dingus"], " is a\u000aweb application that allows you type your own Markdown-formatted text\u000aand translate it to XHTML."], + ["p", ["strong", "Note:"], " This document is itself written using Markdown; you\u000acan ", ["a", { + "href": "/projects/markdown/basics.text" + }, + "see the source for it by adding '.text' to the URL"], "."], "\u000a\u000a", ["h2", "Paragraphs, Headers, Blockquotes"], "\u000a\u000a", ["p", "A paragraph is simply one or more consecutive lines of text, separated\u000aby one or more blank lines. (A blank line is any line that looks like a\u000ablank line -- a line containing nothing spaces or tabs is considered\u000ablank.) Normal paragraphs should not be intended with spaces or tabs."], + ["p", "Markdown offers two styles of headers: ", ["em", "Setext"], " and ", ["em", "atx"], ".\u000aSetext-style headers for ", ["code", "

    "], " and ", ["code", "

    "], " are created by\u000a\"underlining\" with equal signs (", ["code", "="], ") and hyphens (", ["code", "-"], "), respectively.\u000aTo create an atx-style header, you put 1-6 hash marks (", ["code", "#"], ") at the\u000abeginning of the line -- the number of hashes equals the resulting\u000aHTML header level."], + ["p", "Blockquotes are indicated using email-style '", ["code", ">"], "' angle brackets."], + ["p", "Markdown:"], + ["pre", ["code", "A First Level Header\u000a====================\u000a\u000aA Second Level Header\u000a---------------------\u000a\u000aNow is the time for all good men to come to\u000athe aid of their country. This is just a\u000aregular paragraph.\u000a\u000aThe quick brown fox jumped over the lazy\u000adog's back.\u000a\u000a### Header 3\u000a\u000a> This is a blockquote.\u000a> \u000a> This is the second paragraph in the blockquote.\u000a>\u000a> ## This is an H2 in a blockquote\u000a"]], + ["p", "Output:"], + ["pre", ["code", "

    A First Level Header

    \u000a\u000a

    A Second Level Header

    \u000a\u000a

    Now is the time for all good men to come to\u000athe aid of their country. This is just a\u000aregular paragraph.

    \u000a\u000a

    The quick brown fox jumped over the lazy\u000adog's back.

    \u000a\u000a

    Header 3

    \u000a\u000a
    \u000a

    This is a blockquote.

    \u000a\u000a

    This is the second paragraph in the blockquote.

    \u000a\u000a

    This is an H2 in a blockquote

    \u000a
    \u000a"]], "\u000a\u000a", ["h3", "Phrase Emphasis"], "\u000a\u000a", ["p", "Markdown uses asterisks and underscores to indicate spans of emphasis."], + ["p", "Markdown:"], + ["pre", ["code", "Some of these words *are emphasized*.\u000aSome of these words _are emphasized also_.\u000a\u000aUse two asterisks for **strong emphasis**.\u000aOr, if you prefer, __use two underscores instead__.\u000a"]], + ["p", "Output:"], + ["pre", ["code", "

    Some of these words are emphasized.\u000aSome of these words are emphasized also.

    \u000a\u000a

    Use two asterisks for strong emphasis.\u000aOr, if you prefer, use two underscores instead.

    \u000a"]], "\u000a\u000a", ["h2", "Lists"], "\u000a\u000a", ["p", "Unordered (bulleted) lists use asterisks, pluses, and hyphens (", ["code", "*"], ",\u000a", ["code", "+"], ", and ", ["code", "-"], ") as list markers. These three markers are\u000ainterchangable; this:"], + ["pre", ["code", "* Candy.\u000a* Gum.\u000a* Booze.\u000a"]], + ["p", "this:"], + ["pre", ["code", "+ Candy.\u000a+ Gum.\u000a+ Booze.\u000a"]], + ["p", "and this:"], + ["pre", ["code", "- Candy.\u000a- Gum.\u000a- Booze.\u000a"]], + ["p", "all produce the same output:"], + ["pre", ["code", "
      \u000a
    • Candy.
    • \u000a
    • Gum.
    • \u000a
    • Booze.
    • \u000a
    \u000a"]], + ["p", "Ordered (numbered) lists use regular numbers, followed by periods, as\u000alist markers:"], + ["pre", ["code", "1. Red\u000a2. Green\u000a3. Blue\u000a"]], + ["p", "Output:"], + ["pre", ["code", "
      \u000a
    1. Red
    2. \u000a
    3. Green
    4. \u000a
    5. Blue
    6. \u000a
    \u000a"]], + ["p", "If you put blank lines between items, you'll get ", ["code", "

    "], " tags for the\u000alist item text. You can create multi-paragraph list items by indenting\u000athe paragraphs by 4 spaces or 1 tab:"], + ["pre", ["code", "* A list item.\u000a\u000a With multiple paragraphs.\u000a\u000a* Another item in the list.\u000a"]], + ["p", "Output:"], + ["pre", ["code", "

      \u000a
    • A list item.

      \u000a

      With multiple paragraphs.

    • \u000a
    • Another item in the list.

    • \u000a
    \u000a"]], "\u000a\u000a", ["h3", "Links"], "\u000a\u000a", ["p", "Markdown supports two styles for creating links: ", ["em", "inline"], " and\u000a", ["em", "reference"], ". With both styles, you use square brackets to delimit the\u000atext you want to turn into a link."], + ["p", "Inline-style links use parentheses immediately after the link text.\u000aFor example:"], + ["pre", ["code", "This is an [example link](http://example.com/).\u000a"]], + ["p", "Output:"], + ["pre", ["code", "

    This is an \u000aexample link.

    \u000a"]], + ["p", "Optionally, you may include a title attribute in the parentheses:"], + ["pre", ["code", "This is an [example link](http://example.com/ \"With a Title\").\u000a"]], + ["p", "Output:"], + ["pre", ["code", "

    This is an \u000aexample link.

    \u000a"]], + ["p", "Reference-style links allow you to refer to your links by names, which\u000ayou define elsewhere in your document:"], + ["pre", ["code", "I get 10 times more traffic from [Google][1] than from\u000a[Yahoo][2] or [MSN][3].\u000a\u000a[1]: http://google.com/ \"Google\"\u000a[2]: http://search.yahoo.com/ \"Yahoo Search\"\u000a[3]: http://search.msn.com/ \"MSN Search\"\u000a"]], + ["p", "Output:"], + ["pre", ["code", "

    I get 10 times more traffic from Google than from Yahoo or MSN.

    \u000a"]], + ["p", "The title attribute is optional. Link names may contain letters,\u000anumbers and spaces, but are ", ["em", "not"], " case sensitive:"], + ["pre", ["code", "I start my morning with a cup of coffee and\u000a[The New York Times][NY Times].\u000a\u000a[ny times]: http://www.nytimes.com/\u000a"]], + ["p", "Output:"], + ["pre", ["code", "

    I start my morning with a cup of coffee and\u000aThe New York Times.

    \u000a"]], "\u000a\u000a", ["h3", "Images"], "\u000a\u000a", ["p", "Image syntax is very much like link syntax."], + ["p", "Inline (titles are optional):"], + ["pre", ["code", "![alt text](/path/to/img.jpg \"Title\")\u000a"]], + ["p", "Reference-style:"], + ["pre", ["code", "![alt text][id]\u000a\u000a[id]: /path/to/img.jpg \"Title\"\u000a"]], + ["p", "Both of the above examples produce the same output:"], + ["pre", ["code", "\"alt\u000a"]], "\u000a\u000a", ["h3", "Code"], "\u000a\u000a", ["p", "In a regular paragraph, you can create code span by wrapping text in\u000abacktick quotes. Any ampersands (", ["code", "&"], ") and angle brackets (", ["code", "<"], " or\u000a", ["code", ">"], ") will automatically be translated into HTML entities. This makes\u000ait easy to use Markdown to write about HTML example code:"], + ["pre", ["code", "I strongly recommend against using any `` tags.\u000a\u000aI wish SmartyPants used named entities like `—`\u000ainstead of decimal-encoded entites like `—`.\u000a"]], + ["p", "Output:"], + ["pre", ["code", "

    I strongly recommend against using any\u000a<blink> tags.

    \u000a\u000a

    I wish SmartyPants used named entities like\u000a&mdash; instead of decimal-encoded\u000aentites like &#8212;.

    \u000a"]], + ["p", "To specify an entire block of pre-formatted code, indent every line of\u000athe block by 4 spaces or 1 tab. Just like with code spans, ", ["code", "&"], ", ", ["code", "<"], ",\u000aand ", ["code", ">"], " characters will be escaped automatically."], + ["p", "Markdown:"], + ["pre", ["code", "If you want your page to validate under XHTML 1.0 Strict,\u000ayou've got to put paragraph tags in your blockquotes:\u000a\u000a
    \u000a

    For example.

    \u000a
    \u000a"]], + ["p", "Output:"], + ["pre", ["code", "

    If you want your page to validate under XHTML 1.0 Strict,\u000ayou've got to put paragraph tags in your blockquotes:

    \u000a\u000a
    <blockquote>\u000a    <p>For example.</p>\u000a</blockquote>\u000a
    \u000a"]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Basics.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Basics.text new file mode 100644 index 00000000..486055ca --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Basics.text @@ -0,0 +1,306 @@ +Markdown: Basics +================ + + + + +Getting the Gist of Markdown's Formatting Syntax +------------------------------------------------ + +This page offers a brief overview of what it's like to use Markdown. +The [syntax page] [s] provides complete, detailed documentation for +every feature, but Markdown should be very easy to pick up simply by +looking at a few examples of it in action. The examples on this page +are written in a before/after style, showing example syntax and the +HTML output produced by Markdown. + +It's also helpful to simply try Markdown out; the [Dingus] [d] is a +web application that allows you type your own Markdown-formatted text +and translate it to XHTML. + +**Note:** This document is itself written using Markdown; you +can [see the source for it by adding '.text' to the URL] [src]. + + [s]: /projects/markdown/syntax "Markdown Syntax" + [d]: /projects/markdown/dingus "Markdown Dingus" + [src]: /projects/markdown/basics.text + + +## Paragraphs, Headers, Blockquotes ## + +A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs. + +Markdown offers two styles of headers: *Setext* and *atx*. +Setext-style headers for `

    ` and `

    ` are created by +"underlining" with equal signs (`=`) and hyphens (`-`), respectively. +To create an atx-style header, you put 1-6 hash marks (`#`) at the +beginning of the line -- the number of hashes equals the resulting +HTML header level. + +Blockquotes are indicated using email-style '`>`' angle brackets. + +Markdown: + + A First Level Header + ==================== + + A Second Level Header + --------------------- + + Now is the time for all good men to come to + the aid of their country. This is just a + regular paragraph. + + The quick brown fox jumped over the lazy + dog's back. + + ### Header 3 + + > This is a blockquote. + > + > This is the second paragraph in the blockquote. + > + > ## This is an H2 in a blockquote + + +Output: + +

    A First Level Header

    + +

    A Second Level Header

    + +

    Now is the time for all good men to come to + the aid of their country. This is just a + regular paragraph.

    + +

    The quick brown fox jumped over the lazy + dog's back.

    + +

    Header 3

    + +
    +

    This is a blockquote.

    + +

    This is the second paragraph in the blockquote.

    + +

    This is an H2 in a blockquote

    +
    + + + +### Phrase Emphasis ### + +Markdown uses asterisks and underscores to indicate spans of emphasis. + +Markdown: + + Some of these words *are emphasized*. + Some of these words _are emphasized also_. + + Use two asterisks for **strong emphasis**. + Or, if you prefer, __use two underscores instead__. + +Output: + +

    Some of these words are emphasized. + Some of these words are emphasized also.

    + +

    Use two asterisks for strong emphasis. + Or, if you prefer, use two underscores instead.

    + + + +## Lists ## + +Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`, +`+`, and `-`) as list markers. These three markers are +interchangable; this: + + * Candy. + * Gum. + * Booze. + +this: + + + Candy. + + Gum. + + Booze. + +and this: + + - Candy. + - Gum. + - Booze. + +all produce the same output: + +
      +
    • Candy.
    • +
    • Gum.
    • +
    • Booze.
    • +
    + +Ordered (numbered) lists use regular numbers, followed by periods, as +list markers: + + 1. Red + 2. Green + 3. Blue + +Output: + +
      +
    1. Red
    2. +
    3. Green
    4. +
    5. Blue
    6. +
    + +If you put blank lines between items, you'll get `

    ` tags for the +list item text. You can create multi-paragraph list items by indenting +the paragraphs by 4 spaces or 1 tab: + + * A list item. + + With multiple paragraphs. + + * Another item in the list. + +Output: + +

      +
    • A list item.

      +

      With multiple paragraphs.

    • +
    • Another item in the list.

    • +
    + + + +### Links ### + +Markdown supports two styles for creating links: *inline* and +*reference*. With both styles, you use square brackets to delimit the +text you want to turn into a link. + +Inline-style links use parentheses immediately after the link text. +For example: + + This is an [example link](http://example.com/). + +Output: + +

    This is an + example link.

    + +Optionally, you may include a title attribute in the parentheses: + + This is an [example link](http://example.com/ "With a Title"). + +Output: + +

    This is an + example link.

    + +Reference-style links allow you to refer to your links by names, which +you define elsewhere in your document: + + I get 10 times more traffic from [Google][1] than from + [Yahoo][2] or [MSN][3]. + + [1]: http://google.com/ "Google" + [2]: http://search.yahoo.com/ "Yahoo Search" + [3]: http://search.msn.com/ "MSN Search" + +Output: + +

    I get 10 times more traffic from Google than from Yahoo or MSN.

    + +The title attribute is optional. Link names may contain letters, +numbers and spaces, but are *not* case sensitive: + + I start my morning with a cup of coffee and + [The New York Times][NY Times]. + + [ny times]: http://www.nytimes.com/ + +Output: + +

    I start my morning with a cup of coffee and + The New York Times.

    + + +### Images ### + +Image syntax is very much like link syntax. + +Inline (titles are optional): + + ![alt text](/path/to/img.jpg "Title") + +Reference-style: + + ![alt text][id] + + [id]: /path/to/img.jpg "Title" + +Both of the above examples produce the same output: + + alt text + + + +### Code ### + +In a regular paragraph, you can create code span by wrapping text in +backtick quotes. Any ampersands (`&`) and angle brackets (`<` or +`>`) will automatically be translated into HTML entities. This makes +it easy to use Markdown to write about HTML example code: + + I strongly recommend against using any `` tags. + + I wish SmartyPants used named entities like `—` + instead of decimal-encoded entites like `—`. + +Output: + +

    I strongly recommend against using any + <blink> tags.

    + +

    I wish SmartyPants used named entities like + &mdash; instead of decimal-encoded + entites like &#8212;.

    + + +To specify an entire block of pre-formatted code, indent every line of +the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`, +and `>` characters will be escaped automatically. + +Markdown: + + If you want your page to validate under XHTML 1.0 Strict, + you've got to put paragraph tags in your blockquotes: + +
    +

    For example.

    +
    + +Output: + +

    If you want your page to validate under XHTML 1.0 Strict, + you've got to put paragraph tags in your blockquotes:

    + +
    <blockquote>
    +        <p>For example.</p>
    +    </blockquote>
    +    
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Basics.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Basics.xhtml new file mode 100644 index 00000000..d5bdbb29 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Basics.xhtml @@ -0,0 +1,314 @@ +

    Markdown: Basics

    + + + +

    Getting the Gist of Markdown's Formatting Syntax

    + +

    This page offers a brief overview of what it's like to use Markdown. +The syntax page provides complete, detailed documentation for +every feature, but Markdown should be very easy to pick up simply by +looking at a few examples of it in action. The examples on this page +are written in a before/after style, showing example syntax and the +HTML output produced by Markdown.

    + +

    It's also helpful to simply try Markdown out; the Dingus is a +web application that allows you type your own Markdown-formatted text +and translate it to XHTML.

    + +

    Note: This document is itself written using Markdown; you +can see the source for it by adding '.text' to the URL.

    + +

    Paragraphs, Headers, Blockquotes

    + +

    A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs.

    + +

    Markdown offers two styles of headers: Setext and atx. +Setext-style headers for <h1> and <h2> are created by +"underlining" with equal signs (=) and hyphens (-), respectively. +To create an atx-style header, you put 1-6 hash marks (#) at the +beginning of the line -- the number of hashes equals the resulting +HTML header level.

    + +

    Blockquotes are indicated using email-style '>' angle brackets.

    + +

    Markdown:

    + +
    A First Level Header
    +====================
    +
    +A Second Level Header
    +---------------------
    +
    +Now is the time for all good men to come to
    +the aid of their country. This is just a
    +regular paragraph.
    +
    +The quick brown fox jumped over the lazy
    +dog's back.
    +
    +### Header 3
    +
    +> This is a blockquote.
    +> 
    +> This is the second paragraph in the blockquote.
    +>
    +> ## This is an H2 in a blockquote
    +
    + +

    Output:

    + +
    <h1>A First Level Header</h1>
    +
    +<h2>A Second Level Header</h2>
    +
    +<p>Now is the time for all good men to come to
    +the aid of their country. This is just a
    +regular paragraph.</p>
    +
    +<p>The quick brown fox jumped over the lazy
    +dog's back.</p>
    +
    +<h3>Header 3</h3>
    +
    +<blockquote>
    +    <p>This is a blockquote.</p>
    +
    +    <p>This is the second paragraph in the blockquote.</p>
    +
    +    <h2>This is an H2 in a blockquote</h2>
    +</blockquote>
    +
    + +

    Phrase Emphasis

    + +

    Markdown uses asterisks and underscores to indicate spans of emphasis.

    + +

    Markdown:

    + +
    Some of these words *are emphasized*.
    +Some of these words _are emphasized also_.
    +
    +Use two asterisks for **strong emphasis**.
    +Or, if you prefer, __use two underscores instead__.
    +
    + +

    Output:

    + +
    <p>Some of these words <em>are emphasized</em>.
    +Some of these words <em>are emphasized also</em>.</p>
    +
    +<p>Use two asterisks for <strong>strong emphasis</strong>.
    +Or, if you prefer, <strong>use two underscores instead</strong>.</p>
    +
    + +

    Lists

    + +

    Unordered (bulleted) lists use asterisks, pluses, and hyphens (*, ++, and -) as list markers. These three markers are +interchangable; this:

    + +
    *   Candy.
    +*   Gum.
    +*   Booze.
    +
    + +

    this:

    + +
    +   Candy.
    ++   Gum.
    ++   Booze.
    +
    + +

    and this:

    + +
    -   Candy.
    +-   Gum.
    +-   Booze.
    +
    + +

    all produce the same output:

    + +
    <ul>
    +<li>Candy.</li>
    +<li>Gum.</li>
    +<li>Booze.</li>
    +</ul>
    +
    + +

    Ordered (numbered) lists use regular numbers, followed by periods, as +list markers:

    + +
    1.  Red
    +2.  Green
    +3.  Blue
    +
    + +

    Output:

    + +
    <ol>
    +<li>Red</li>
    +<li>Green</li>
    +<li>Blue</li>
    +</ol>
    +
    + +

    If you put blank lines between items, you'll get <p> tags for the +list item text. You can create multi-paragraph list items by indenting +the paragraphs by 4 spaces or 1 tab:

    + +
    *   A list item.
    +
    +    With multiple paragraphs.
    +
    +*   Another item in the list.
    +
    + +

    Output:

    + +
    <ul>
    +<li><p>A list item.</p>
    +<p>With multiple paragraphs.</p></li>
    +<li><p>Another item in the list.</p></li>
    +</ul>
    +
    + +

    Links

    + +

    Markdown supports two styles for creating links: inline and +reference. With both styles, you use square brackets to delimit the +text you want to turn into a link.

    + +

    Inline-style links use parentheses immediately after the link text. +For example:

    + +
    This is an [example link](http://example.com/).
    +
    + +

    Output:

    + +
    <p>This is an <a href="http://example.com/">
    +example link</a>.</p>
    +
    + +

    Optionally, you may include a title attribute in the parentheses:

    + +
    This is an [example link](http://example.com/ "With a Title").
    +
    + +

    Output:

    + +
    <p>This is an <a href="http://example.com/" title="With a Title">
    +example link</a>.</p>
    +
    + +

    Reference-style links allow you to refer to your links by names, which +you define elsewhere in your document:

    + +
    I get 10 times more traffic from [Google][1] than from
    +[Yahoo][2] or [MSN][3].
    +
    +[1]: http://google.com/        "Google"
    +[2]: http://search.yahoo.com/  "Yahoo Search"
    +[3]: http://search.msn.com/    "MSN Search"
    +
    + +

    Output:

    + +
    <p>I get 10 times more traffic from <a href="http://google.com/"
    +title="Google">Google</a> than from <a href="http://search.yahoo.com/"
    +title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
    +title="MSN Search">MSN</a>.</p>
    +
    + +

    The title attribute is optional. Link names may contain letters, +numbers and spaces, but are not case sensitive:

    + +
    I start my morning with a cup of coffee and
    +[The New York Times][NY Times].
    +
    +[ny times]: http://www.nytimes.com/
    +
    + +

    Output:

    + +
    <p>I start my morning with a cup of coffee and
    +<a href="http://www.nytimes.com/">The New York Times</a>.</p>
    +
    + +

    Images

    + +

    Image syntax is very much like link syntax.

    + +

    Inline (titles are optional):

    + +
    ![alt text](/path/to/img.jpg "Title")
    +
    + +

    Reference-style:

    + +
    ![alt text][id]
    +
    +[id]: /path/to/img.jpg "Title"
    +
    + +

    Both of the above examples produce the same output:

    + +
    <img src="/path/to/img.jpg" alt="alt text" title="Title" />
    +
    + +

    Code

    + +

    In a regular paragraph, you can create code span by wrapping text in +backtick quotes. Any ampersands (&) and angle brackets (< or +>) will automatically be translated into HTML entities. This makes +it easy to use Markdown to write about HTML example code:

    + +
    I strongly recommend against using any `<blink>` tags.
    +
    +I wish SmartyPants used named entities like `&mdash;`
    +instead of decimal-encoded entites like `&#8212;`.
    +
    + +

    Output:

    + +
    <p>I strongly recommend against using any
    +<code>&lt;blink&gt;</code> tags.</p>
    +
    +<p>I wish SmartyPants used named entities like
    +<code>&amp;mdash;</code> instead of decimal-encoded
    +entites like <code>&amp;#8212;</code>.</p>
    +
    + +

    To specify an entire block of pre-formatted code, indent every line of +the block by 4 spaces or 1 tab. Just like with code spans, &, <, +and > characters will be escaped automatically.

    + +

    Markdown:

    + +
    If you want your page to validate under XHTML 1.0 Strict,
    +you've got to put paragraph tags in your blockquotes:
    +
    +    <blockquote>
    +        <p>For example.</p>
    +    </blockquote>
    +
    + +

    Output:

    + +
    <p>If you want your page to validate under XHTML 1.0 Strict,
    +you've got to put paragraph tags in your blockquotes:</p>
    +
    +<pre><code>&lt;blockquote&gt;
    +    &lt;p&gt;For example.&lt;/p&gt;
    +&lt;/blockquote&gt;
    +</code></pre>
    +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Syntax.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Syntax.json new file mode 100644 index 00000000..a8c819df --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Syntax.json @@ -0,0 +1,393 @@ +["html", ["h1", "Markdown: Syntax"], "\u000a\u000a", ["ul", { + "id": "ProjectSubmenu" +}, +["li", ["a", { + "href": "/projects/markdown/", + "title": "Markdown Project Page" +}, +"Main"]], + ["li", ["a", { + "href": "/projects/markdown/basics", + "title": "Markdown Basics" + }, + "Basics"]], + ["li", ["a", { + "class": "selected", + "title": "Markdown Syntax Documentation" + }, + "Syntax"]], + ["li", ["a", { + "href": "/projects/markdown/license", + "title": "Pricing and License Information" + }, + "License"]], + ["li", ["a", { + "href": "/projects/markdown/dingus", + "title": "Online Markdown Web Form" + }, + "Dingus"]]], + ["ul", ["li", ["a", { + "href": "#overview" + }, + "Overview"], "\u000a", ["ul", ["li", ["a", { + "href": "#philosophy" + }, + "Philosophy"]], + ["li", ["a", { + "href": "#html" + }, + "Inline HTML"]], + ["li", ["a", { + "href": "#autoescape" + }, + "Automatic Escaping for Special Characters"]]]], + ["li", ["a", { + "href": "#block" + }, + "Block Elements"], "\u000a", ["ul", ["li", ["a", { + "href": "#p" + }, + "Paragraphs and Line Breaks"]], + ["li", ["a", { + "href": "#header" + }, + "Headers"]], + ["li", ["a", { + "href": "#blockquote" + }, + "Blockquotes"]], + ["li", ["a", { + "href": "#list" + }, + "Lists"]], + ["li", ["a", { + "href": "#precode" + }, + "Code Blocks"]], + ["li", ["a", { + "href": "#hr" + }, + "Horizontal Rules"]]]], + ["li", ["a", { + "href": "#span" + }, + "Span Elements"], "\u000a", ["ul", ["li", ["a", { + "href": "#link" + }, + "Links"]], + ["li", ["a", { + "href": "#em" + }, + "Emphasis"]], + ["li", ["a", { + "href": "#code" + }, + "Code"]], + ["li", ["a", { + "href": "#img" + }, + "Images"]]]], + ["li", ["a", { + "href": "#misc" + }, + "Miscellaneous"], "\u000a", ["ul", ["li", ["a", { + "href": "#backslash" + }, + "Backslash Escapes"]], + ["li", ["a", { + "href": "#autolink" + }, + "Automatic Links"]]]]], + ["p", ["strong", "Note:"], " This document is itself written using Markdown; you\u000acan ", ["a", { + "href": "/projects/markdown/syntax.text" + }, + "see the source for it by adding '.text' to the URL"], "."], "\u000a\u000a", ["hr"], "\u000a\u000a", ["h2", { + "id": "overview" +}, +"Overview"], "\u000a\u000a", ["h3", { + "id": "philosophy" +}, +"Philosophy"], "\u000a\u000a", ["p", "Markdown is intended to be as easy-to-read and easy-to-write as is feasible."], + ["p", "Readability, however, is emphasized above all else. A Markdown-formatted\u000adocument should be publishable as-is, as plain text, without looking\u000alike it's been marked up with tags or formatting instructions. While\u000aMarkdown's syntax has been influenced by several existing text-to-HTML\u000afilters -- including ", ["a", { + "href": "http://docutils.sourceforge.net/mirror/setext.html" + }, + "Setext"], ", ", ["a", { + "href": "http://www.aaronsw.com/2002/atx/" + }, + "atx"], ", ", ["a", { + "href": "http://textism.com/tools/textile/" + }, + "Textile"], ", ", ["a", { + "href": "http://docutils.sourceforge.net/rst.html" + }, + "reStructuredText"], ",\u000a", ["a", { + "href": "http://www.triptico.com/software/grutatxt.html" + }, + "Grutatext"], ", and ", ["a", { + "href": "http://ettext.taint.org/doc/" + }, + "EtText"], " -- the single biggest source of\u000ainspiration for Markdown's syntax is the format of plain text email."], + ["p", "To this end, Markdown's syntax is comprised entirely of punctuation\u000acharacters, which punctuation characters have been carefully chosen so\u000aas to look like what they mean. E.g., asterisks around a word actually\u000alook like *emphasis*. Markdown lists look like, well, lists. Even\u000ablockquotes look like quoted passages of text, assuming you've ever\u000aused email."], "\u000a\u000a", ["h3", { + "id": "html" +}, +"Inline HTML"], "\u000a\u000a", ["p", "Markdown's syntax is intended for one purpose: to be used as a\u000aformat for ", ["em", "writing"], " for the web."], + ["p", "Markdown is not a replacement for HTML, or even close to it. Its\u000asyntax is very small, corresponding only to a very small subset of\u000aHTML tags. The idea is ", ["em", "not"], " to create a syntax that makes it easier\u000ato insert HTML tags. In my opinion, HTML tags are already easy to\u000ainsert. The idea for Markdown is to make it easy to read, write, and\u000aedit prose. HTML is a ", ["em", "publishing"], " format; Markdown is a ", ["em", "writing"], "\u000aformat. Thus, Markdown's formatting syntax only addresses issues that\u000acan be conveyed in plain text."], + ["p", "For any markup that is not covered by Markdown's syntax, you simply\u000ause HTML itself. There's no need to preface it or delimit it to\u000aindicate that you're switching from Markdown to HTML; you just use\u000athe tags."], + ["p", "The only restrictions are that block-level HTML elements -- e.g. ", ["code", "
    "], ",\u000a", ["code", ""], ", ", ["code", "
    "], ", ", ["code", "

    "], ", etc. -- must be separated from surrounding\u000acontent by blank lines, and the start and end tags of the block should\u000anot be indented with tabs or spaces. Markdown is smart enough not\u000ato add extra (unwanted) ", ["code", "

    "], " tags around HTML block-level tags."], + ["p", "For example, to add an HTML table to a Markdown article:"], + ["pre", ["code", "This is a regular paragraph.\u000a\u000a

    \u000a \u000a \u000a \u000a
    Foo
    \u000a\u000aThis is another regular paragraph.\u000a"]], + ["p", "Note that Markdown formatting syntax is not processed within block-level\u000aHTML tags. E.g., you can't use Markdown-style ", ["code", "*emphasis*"], " inside an\u000aHTML block."], + ["p", "Span-level HTML tags -- e.g. ", ["code", ""], ", ", ["code", ""], ", or ", ["code", ""], " -- can be\u000aused anywhere in a Markdown paragraph, list item, or header. If you\u000awant, you can even use HTML tags instead of Markdown formatting; e.g. if\u000ayou'd prefer to use HTML ", ["code", ""], " or ", ["code", ""], " tags instead of Markdown's\u000alink or image syntax, go right ahead."], + ["p", "Unlike block-level HTML tags, Markdown syntax ", ["em", "is"], " processed within\u000aspan-level tags."], "\u000a\u000a", ["h3", { + "id": "autoescape" +}, +"Automatic Escaping for Special Characters"], "\u000a\u000a", ["p", "In HTML, there are two characters that demand special treatment: ", ["code", "<"], "\u000aand ", ["code", "&"], ". Left angle brackets are used to start tags; ampersands are\u000aused to denote HTML entities. If you want to use them as literal\u000acharacters, you must escape them as entities, e.g. ", ["code", "<"], ", and\u000a", ["code", "&"], "."], + ["p", "Ampersands in particular are bedeviling for web writers. If you want to\u000awrite about 'AT&T', you need to write '", ["code", "AT&T"], "'. You even need to\u000aescape ampersands within URLs. Thus, if you want to link to:"], + ["pre", ["code", "http://images.google.com/images?num=30&q=larry+bird\u000a"]], + ["p", "you need to encode the URL as:"], + ["pre", ["code", "http://images.google.com/images?num=30&q=larry+bird\u000a"]], + ["p", "in your anchor tag ", ["code", "href"], " attribute. Needless to say, this is easy to\u000aforget, and is probably the single most common source of HTML validation\u000aerrors in otherwise well-marked-up web sites."], + ["p", "Markdown allows you to use these characters naturally, taking care of\u000aall the necessary escaping for you. If you use an ampersand as part of\u000aan HTML entity, it remains unchanged; otherwise it will be translated\u000ainto ", ["code", "&"], "."], + ["p", "So, if you want to include a copyright symbol in your article, you can write:"], + ["pre", ["code", "©\u000a"]], + ["p", "and Markdown will leave it alone. But if you write:"], + ["pre", ["code", "AT&T\u000a"]], + ["p", "Markdown will translate it to:"], + ["pre", ["code", "AT&T\u000a"]], + ["p", "Similarly, because Markdown supports ", ["a", { + "href": "#html" + }, + "inline HTML"], ", if you use\u000aangle brackets as delimiters for HTML tags, Markdown will treat them as\u000asuch. But if you write:"], + ["pre", ["code", "4 < 5\u000a"]], + ["p", "Markdown will translate it to:"], + ["pre", ["code", "4 < 5\u000a"]], + ["p", "However, inside Markdown code spans and blocks, angle brackets and\u000aampersands are ", ["em", "always"], " encoded automatically. This makes it easy to use\u000aMarkdown to write about HTML code. (As opposed to raw HTML, which is a\u000aterrible format for writing about HTML syntax, because every single ", ["code", "<"], "\u000aand ", ["code", "&"], " in your example code needs to be escaped.)"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["h2", { + "id": "block" +}, +"Block Elements"], "\u000a\u000a", ["h3", { + "id": "p" +}, +"Paragraphs and Line Breaks"], "\u000a\u000a", ["p", "A paragraph is simply one or more consecutive lines of text, separated\u000aby one or more blank lines. (A blank line is any line that looks like a\u000ablank line -- a line containing nothing but spaces or tabs is considered\u000ablank.) Normal paragraphs should not be intended with spaces or tabs."], + ["p", "The implication of the \"one or more consecutive lines of text\" rule is\u000athat Markdown supports \"hard-wrapped\" text paragraphs. This differs\u000asignificantly from most other text-to-HTML formatters (including Movable\u000aType's \"Convert Line Breaks\" option) which translate every line break\u000acharacter in a paragraph into a ", ["code", "
    "], " tag."], + ["p", "When you ", ["em", "do"], " want to insert a ", ["code", "
    "], " break tag using Markdown, you\u000aend a line with two or more spaces, then type return."], + ["p", "Yes, this takes a tad more effort to create a ", ["code", "
    "], ", but a simplistic\u000a\"every line break is a ", ["code", "
    "], "\" rule wouldn't work for Markdown.\u000aMarkdown's email-style ", ["a", { + "href": "#blockquote" + }, + "blockquoting"], " and multi-paragraph ", ["a", { + "href": "#list" + }, + "list items"], "\u000awork best -- and look better -- when you format them with hard breaks."], "\u000a\u000a", ["h3", { + "id": "header" +}, +"Headers"], "\u000a\u000a", ["p", "Markdown supports two styles of headers, ", ["a", { + "href": "http://docutils.sourceforge.net/mirror/setext.html" +}, +"Setext"], " and ", ["a", { + "href": "http://www.aaronsw.com/2002/atx/" +}, +"atx"], "."], + ["p", "Setext-style headers are \"underlined\" using equal signs (for first-level\u000aheaders) and dashes (for second-level headers). For example:"], + ["pre", ["code", "This is an H1\u000a=============\u000a\u000aThis is an H2\u000a-------------\u000a"]], + ["p", "Any number of underlining ", ["code", "="], "'s or ", ["code", "-"], "'s will work."], + ["p", "Atx-style headers use 1-6 hash characters at the start of the line,\u000acorresponding to header levels 1-6. For example:"], + ["pre", ["code", "# This is an H1\u000a\u000a## This is an H2\u000a\u000a###### This is an H6\u000a"]], + ["p", "Optionally, you may \"close\" atx-style headers. This is purely\u000acosmetic -- you can use this if you think it looks better. The\u000aclosing hashes don't even need to match the number of hashes\u000aused to open the header. (The number of opening hashes\u000adetermines the header level.) :"], + ["pre", ["code", "# This is an H1 #\u000a\u000a## This is an H2 ##\u000a\u000a### This is an H3 ######\u000a"]], "\u000a\u000a", ["h3", { + "id": "blockquote" +}, +"Blockquotes"], "\u000a\u000a", ["p", "Markdown uses email-style ", ["code", ">"], " characters for blockquoting. If you're\u000afamiliar with quoting passages of text in an email message, then you\u000aknow how to create a blockquote in Markdown. It looks best if you hard\u000awrap the text and put a ", ["code", ">"], " before every line:"], + ["pre", ["code", "> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,\u000a> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.\u000a> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.\u000a> \u000a> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse\u000a> id sem consectetuer libero luctus adipiscing.\u000a"]], + ["p", "Markdown allows you to be lazy and only put the ", ["code", ">"], " before the first\u000aline of a hard-wrapped paragraph:"], + ["pre", ["code", "> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,\u000aconsectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.\u000aVestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.\u000a\u000a> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse\u000aid sem consectetuer libero luctus adipiscing.\u000a"]], + ["p", "Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by\u000aadding additional levels of ", ["code", ">"], ":"], + ["pre", ["code", "> This is the first level of quoting.\u000a>\u000a> > This is nested blockquote.\u000a>\u000a> Back to the first level.\u000a"]], + ["p", "Blockquotes can contain other Markdown elements, including headers, lists,\u000aand code blocks:"], + ["pre", ["code", "> ## This is a header.\u000a> \u000a> 1. This is the first list item.\u000a> 2. This is the second list item.\u000a> \u000a> Here's some example code:\u000a> \u000a> return shell_exec(\"echo $input | $markdown_script\");\u000a"]], + ["p", "Any decent text editor should make email-style quoting easy. For\u000aexample, with BBEdit, you can make a selection and choose Increase\u000aQuote Level from the Text menu."], "\u000a\u000a", ["h3", { + "id": "list" +}, +"Lists"], "\u000a\u000a", ["p", "Markdown supports ordered (numbered) and unordered (bulleted) lists."], + ["p", "Unordered lists use asterisks, pluses, and hyphens -- interchangably\u000a-- as list markers:"], + ["pre", ["code", "* Red\u000a* Green\u000a* Blue\u000a"]], + ["p", "is equivalent to:"], + ["pre", ["code", "+ Red\u000a+ Green\u000a+ Blue\u000a"]], + ["p", "and:"], + ["pre", ["code", "- Red\u000a- Green\u000a- Blue\u000a"]], + ["p", "Ordered lists use numbers followed by periods:"], + ["pre", ["code", "1. Bird\u000a2. McHale\u000a3. Parish\u000a"]], + ["p", "It's important to note that the actual numbers you use to mark the\u000alist have no effect on the HTML output Markdown produces. The HTML\u000aMarkdown produces from the above list is:"], + ["pre", ["code", "
      \u000a
    1. Bird
    2. \u000a
    3. McHale
    4. \u000a
    5. Parish
    6. \u000a
    \u000a"]], + ["p", "If you instead wrote the list in Markdown like this:"], + ["pre", ["code", "1. Bird\u000a1. McHale\u000a1. Parish\u000a"]], + ["p", "or even:"], + ["pre", ["code", "3. Bird\u000a1. McHale\u000a8. Parish\u000a"]], + ["p", "you'd get the exact same HTML output. The point is, if you want to,\u000ayou can use ordinal numbers in your ordered Markdown lists, so that\u000athe numbers in your source match the numbers in your published HTML.\u000aBut if you want to be lazy, you don't have to."], + ["p", "If you do use lazy list numbering, however, you should still start the\u000alist with the number 1. At some point in the future, Markdown may support\u000astarting ordered lists at an arbitrary number."], + ["p", "List markers typically start at the left margin, but may be indented by\u000aup to three spaces. List markers must be followed by one or more spaces\u000aor a tab."], + ["p", "To make lists look nice, you can wrap items with hanging indents:"], + ["pre", ["code", "* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\u000a Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,\u000a viverra nec, fringilla in, laoreet vitae, risus.\u000a* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.\u000a Suspendisse id sem consectetuer libero luctus adipiscing.\u000a"]], + ["p", "But if you want to be lazy, you don't have to:"], + ["pre", ["code", "* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\u000aAliquam hendrerit mi posuere lectus. Vestibulum enim wisi,\u000aviverra nec, fringilla in, laoreet vitae, risus.\u000a* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.\u000aSuspendisse id sem consectetuer libero luctus adipiscing.\u000a"]], + ["p", "If list items are separated by blank lines, Markdown will wrap the\u000aitems in ", ["code", "

    "], " tags in the HTML output. For example, this input:"], + ["pre", ["code", "* Bird\u000a* Magic\u000a"]], + ["p", "will turn into:"], + ["pre", ["code", "

      \u000a
    • Bird
    • \u000a
    • Magic
    • \u000a
    \u000a"]], + ["p", "But this:"], + ["pre", ["code", "* Bird\u000a\u000a* Magic\u000a"]], + ["p", "will turn into:"], + ["pre", ["code", "
      \u000a
    • Bird

    • \u000a
    • Magic

    • \u000a
    \u000a"]], + ["p", "List items may consist of multiple paragraphs. Each subsequent\u000aparagraph in a list item must be intended by either 4 spaces\u000aor one tab:"], + ["pre", ["code", "1. This is a list item with two paragraphs. Lorem ipsum dolor\u000a sit amet, consectetuer adipiscing elit. Aliquam hendrerit\u000a mi posuere lectus.\u000a\u000a Vestibulum enim wisi, viverra nec, fringilla in, laoreet\u000a vitae, risus. Donec sit amet nisl. Aliquam semper ipsum\u000a sit amet velit.\u000a\u000a2. Suspendisse id sem consectetuer libero luctus adipiscing.\u000a"]], + ["p", "It looks nice if you indent every line of the subsequent\u000aparagraphs, but here again, Markdown will allow you to be\u000alazy:"], + ["pre", ["code", "* This is a list item with two paragraphs.\u000a\u000a This is the second paragraph in the list item. You're\u000aonly required to indent the first line. Lorem ipsum dolor\u000asit amet, consectetuer adipiscing elit.\u000a\u000a* Another item in the same list.\u000a"]], + ["p", "To put a blockquote within a list item, the blockquote's ", ["code", ">"], "\u000adelimiters need to be indented:"], + ["pre", ["code", "* A list item with a blockquote:\u000a\u000a > This is a blockquote\u000a > inside a list item.\u000a"]], + ["p", "To put a code block within a list item, the code block needs\u000ato be indented ", ["em", "twice"], " -- 8 spaces or two tabs:"], + ["pre", ["code", "* A list item with a code block:\u000a\u000a \u000a"]], + ["p", "It's worth noting that it's possible to trigger an ordered list by\u000aaccident, by writing something like this:"], + ["pre", ["code", "1986. What a great season.\u000a"]], + ["p", "In other words, a ", ["em", "number-period-space"], " sequence at the beginning of a\u000aline. To avoid this, you can backslash-escape the period:"], + ["pre", ["code", "1986\\. What a great season.\u000a"]], "\u000a\u000a", ["h3", { + "id": "precode" +}, +"Code Blocks"], "\u000a\u000a", ["p", "Pre-formatted code blocks are used for writing about programming or\u000amarkup source code. Rather than forming normal paragraphs, the lines\u000aof a code block are interpreted literally. Markdown wraps a code block\u000ain both ", ["code", "
    "], " and ", ["code", ""], " tags."],
    +    ["p", "To produce a code block in Markdown, simply indent every line of the\u000ablock by at least 4 spaces or 1 tab. For example, given this input:"],
    +    ["pre", ["code", "This is a normal paragraph:\u000a\u000a    This is a code block.\u000a"]],
    +    ["p", "Markdown will generate:"],
    +    ["pre", ["code", "

    This is a normal paragraph:

    \u000a\u000a
    This is a code block.\u000a
    \u000a"]], + ["p", "One level of indentation -- 4 spaces or 1 tab -- is removed from each\u000aline of the code block. For example, this:"], + ["pre", ["code", "Here is an example of AppleScript:\u000a\u000a tell application \"Foo\"\u000a beep\u000a end tell\u000a"]], + ["p", "will turn into:"], + ["pre", ["code", "

    Here is an example of AppleScript:

    \u000a\u000a
    tell application \"Foo\"\u000a    beep\u000aend tell\u000a
    \u000a"]], + ["p", "A code block continues until it reaches a line that is not indented\u000a(or the end of the article)."], + ["p", "Within a code block, ampersands (", ["code", "&"], ") and angle brackets (", ["code", "<"], " and ", ["code", ">"], ")\u000aare automatically converted into HTML entities. This makes it very\u000aeasy to include example HTML source code using Markdown -- just paste\u000ait and indent it, and Markdown will handle the hassle of encoding the\u000aampersands and angle brackets. For example, this:"], + ["pre", ["code", "
    \u000a © 2004 Foo Corporation\u000a
    \u000a"]], + ["p", "will turn into:"], + ["pre", ["code", "
    <div class=\"footer\">\u000a    &copy; 2004 Foo Corporation\u000a</div>\u000a
    \u000a"]], + ["p", "Regular Markdown syntax is not processed within code blocks. E.g.,\u000aasterisks are just literal asterisks within a code block. This means\u000ait's also easy to use Markdown to write about Markdown's own syntax."], "\u000a\u000a", ["h3", { + "id": "hr" +}, +"Horizontal Rules"], "\u000a\u000a", ["p", "You can produce a horizontal rule tag (", ["code", "
    "], ") by placing three or\u000amore hyphens, asterisks, or underscores on a line by themselves. If you\u000awish, you may use spaces between the hyphens or asterisks. Each of the\u000afollowing lines will produce a horizontal rule:"], + ["pre", ["code", "* * *\u000a\u000a***\u000a\u000a*****\u000a\u000a- - -\u000a\u000a---------------------------------------\u000a\u000a_ _ _\u000a"]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["h2", { + "id": "span" +}, +"Span Elements"], "\u000a\u000a", ["h3", { + "id": "link" +}, +"Links"], "\u000a\u000a", ["p", "Markdown supports two style of links: ", ["em", "inline"], " and ", ["em", "reference"], "."], + ["p", "In both styles, the link text is delimited by [square brackets]."], + ["p", "To create an inline link, use a set of regular parentheses immediately\u000aafter the link text's closing square bracket. Inside the parentheses,\u000aput the URL where you want the link to point, along with an ", ["em", "optional"], "\u000atitle for the link, surrounded in quotes. For example:"], + ["pre", ["code", "This is [an example](http://example.com/ \"Title\") inline link.\u000a\u000a[This link](http://example.net/) has no title attribute.\u000a"]], + ["p", "Will produce:"], + ["pre", ["code", "

    This is \u000aan example inline link.

    \u000a\u000a

    This link has no\u000atitle attribute.

    \u000a"]], + ["p", "If you're referring to a local resource on the same server, you can\u000ause relative paths:"], + ["pre", ["code", "See my [About](/about/) page for details.\u000a"]], + ["p", "Reference-style links use a second set of square brackets, inside\u000awhich you place a label of your choosing to identify the link:"], + ["pre", ["code", "This is [an example][id] reference-style link.\u000a"]], + ["p", "You can optionally use a space to separate the sets of brackets:"], + ["pre", ["code", "This is [an example] [id] reference-style link.\u000a"]], + ["p", "Then, anywhere in the document, you define your link label like this,\u000aon a line by itself:"], + ["pre", ["code", "[id]: http://example.com/ \"Optional Title Here\"\u000a"]], + ["p", "That is:"], + ["ul", ["li", "Square brackets containing the link identifier (optionally\u000aindented from the left margin using up to three spaces);"], + ["li", "followed by a colon;"], + ["li", "followed by one or more spaces (or tabs);"], + ["li", "followed by the URL for the link;"], + ["li", "optionally followed by a title attribute for the link, enclosed\u000ain double or single quotes."]], + ["p", "The link URL may, optionally, be surrounded by angle brackets:"], + ["pre", ["code", "[id]: \"Optional Title Here\"\u000a"]], + ["p", "You can put the title attribute on the next line and use extra spaces\u000aor tabs for padding, which tends to look better with longer URLs:"], + ["pre", ["code", "[id]: http://example.com/longish/path/to/resource/here\u000a \"Optional Title Here\"\u000a"]], + ["p", "Link definitions are only used for creating links during Markdown\u000aprocessing, and are stripped from your document in the HTML output."], + ["p", "Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are ", ["em", "not"], " case sensitive. E.g. these two links:"], + ["pre", ["code", "[link text][a]\u000a[link text][A]\u000a"]], + ["p", "are equivalent."], + ["p", "The ", ["em", "implicit link name"], " shortcut allows you to omit the name of the\u000alink, in which case the link text itself is used as the name.\u000aJust use an empty set of square brackets -- e.g., to link the word\u000a\"Google\" to the google.com web site, you could simply write:"], + ["pre", ["code", "[Google][]\u000a"]], + ["p", "And then define the link:"], + ["pre", ["code", "[Google]: http://google.com/\u000a"]], + ["p", "Because link names may contain spaces, this shortcut even works for\u000amultiple words in the link text:"], + ["pre", ["code", "Visit [Daring Fireball][] for more information.\u000a"]], + ["p", "And then define the link:"], + ["pre", ["code", "[Daring Fireball]: http://daringfireball.net/\u000a"]], + ["p", "Link definitions can be placed anywhere in your Markdown document. I\u000atend to put them immediately after each paragraph in which they're\u000aused, but if you want, you can put them all at the end of your\u000adocument, sort of like footnotes."], + ["p", "Here's an example of reference links in action:"], + ["pre", ["code", "I get 10 times more traffic from [Google] [1] than from\u000a[Yahoo] [2] or [MSN] [3].\u000a\u000a [1]: http://google.com/ \"Google\"\u000a [2]: http://search.yahoo.com/ \"Yahoo Search\"\u000a [3]: http://search.msn.com/ \"MSN Search\"\u000a"]], + ["p", "Using the implicit link name shortcut, you could instead write:"], + ["pre", ["code", "I get 10 times more traffic from [Google][] than from\u000a[Yahoo][] or [MSN][].\u000a\u000a [google]: http://google.com/ \"Google\"\u000a [yahoo]: http://search.yahoo.com/ \"Yahoo Search\"\u000a [msn]: http://search.msn.com/ \"MSN Search\"\u000a"]], + ["p", "Both of the above examples will produce the following HTML output:"], + ["pre", ["code", "

    I get 10 times more traffic from Google than from\u000aYahoo\u000aor MSN.

    \u000a"]], + ["p", "For comparison, here is the same paragraph written using\u000aMarkdown's inline link style:"], + ["pre", ["code", "I get 10 times more traffic from [Google](http://google.com/ \"Google\")\u000athan from [Yahoo](http://search.yahoo.com/ \"Yahoo Search\") or\u000a[MSN](http://search.msn.com/ \"MSN Search\").\u000a"]], + ["p", "The point of reference-style links is not that they're easier to\u000awrite. The point is that with reference-style links, your document\u000asource is vastly more readable. Compare the above examples: using\u000areference-style links, the paragraph itself is only 81 characters\u000along; with inline-style links, it's 176 characters; and as raw HTML,\u000ait's 234 characters. In the raw HTML, there's more markup than there\u000ais text."], + ["p", "With Markdown's reference-style links, a source document much more\u000aclosely resembles the final output, as rendered in a browser. By\u000aallowing you to move the markup-related metadata out of the paragraph,\u000ayou can add links without interrupting the narrative flow of your\u000aprose."], "\u000a\u000a", ["h3", { + "id": "em" +}, +"Emphasis"], "\u000a\u000a", ["p", "Markdown treats asterisks (", ["code", "*"], ") and underscores (", ["code", "_"], ") as indicators of\u000aemphasis. Text wrapped with one ", ["code", "*"], " or ", ["code", "_"], " will be wrapped with an\u000aHTML ", ["code", ""], " tag; double ", ["code", "*"], "'s or ", ["code", "_"], "'s will be wrapped with an HTML\u000a", ["code", ""], " tag. E.g., this input:"], + ["pre", ["code", "*single asterisks*\u000a\u000a_single underscores_\u000a\u000a**double asterisks**\u000a\u000a__double underscores__\u000a"]], + ["p", "will produce:"], + ["pre", ["code", "single asterisks\u000a\u000asingle underscores\u000a\u000adouble asterisks\u000a\u000adouble underscores\u000a"]], + ["p", "You can use whichever style you prefer; the lone restriction is that\u000athe same character must be used to open and close an emphasis span."], + ["p", "Emphasis can be used in the middle of a word:"], + ["pre", ["code", "un*fucking*believable\u000a"]], + ["p", "But if you surround an ", ["code", "*"], " or ", ["code", "_"], " with spaces, it'll be treated as a\u000aliteral asterisk or underscore."], + ["p", "To produce a literal asterisk or underscore at a position where it\u000awould otherwise be used as an emphasis delimiter, you can backslash\u000aescape it:"], + ["pre", ["code", "\\*this text is surrounded by literal asterisks\\*\u000a"]], "\u000a\u000a", ["h3", { + "id": "code" +}, +"Code"], "\u000a\u000a", ["p", "To indicate a span of code, wrap it with backtick quotes (", ["code", "`"], ").\u000aUnlike a pre-formatted code block, a code span indicates code within a\u000anormal paragraph. For example:"], + ["pre", ["code", "Use the `printf()` function.\u000a"]], + ["p", "will produce:"], + ["pre", ["code", "

    Use the printf() function.

    \u000a"]], + ["p", "To include a literal backtick character within a code span, you can use\u000amultiple backticks as the opening and closing delimiters:"], + ["pre", ["code", "``There is a literal backtick (`) here.``\u000a"]], + ["p", "which will produce this:"], + ["pre", ["code", "

    There is a literal backtick (`) here.

    \u000a"]], + ["p", "The backtick delimiters surrounding a code span may include spaces --\u000aone after the opening, one before the closing. This allows you to place\u000aliteral backtick characters at the beginning or end of a code span:"], + ["pre", ["code", "A single backtick in a code span: `` ` ``\u000a\u000aA backtick-delimited string in a code span: `` `foo` ``\u000a"]], + ["p", "will produce:"], + ["pre", ["code", "

    A single backtick in a code span: `

    \u000a\u000a

    A backtick-delimited string in a code span: `foo`

    \u000a"]], + ["p", "With a code span, ampersands and angle brackets are encoded as HTML\u000aentities automatically, which makes it easy to include example HTML\u000atags. Markdown will turn this:"], + ["pre", ["code", "Please don't use any `` tags.\u000a"]], + ["p", "into:"], + ["pre", ["code", "

    Please don't use any <blink> tags.

    \u000a"]], + ["p", "You can write this:"], + ["pre", ["code", "`—` is the decimal-encoded equivalent of `—`.\u000a"]], + ["p", "to produce:"], + ["pre", ["code", "

    &#8212; is the decimal-encoded\u000aequivalent of &mdash;.

    \u000a"]], "\u000a\u000a", ["h3", { + "id": "img" +}, +"Images"], "\u000a\u000a", ["p", "Admittedly, it's fairly difficult to devise a \"natural\" syntax for\u000aplacing images into a plain text document format."], + ["p", "Markdown uses an image syntax that is intended to resemble the syntax\u000afor links, allowing for two styles: ", ["em", "inline"], " and ", ["em", "reference"], "."], + ["p", "Inline image syntax looks like this:"], + ["pre", ["code", "![Alt text](/path/to/img.jpg)\u000a\u000a![Alt text](/path/to/img.jpg \"Optional title\")\u000a"]], + ["p", "That is:"], + ["ul", ["li", "An exclamation mark: ", ["code", "!"], ";"], + ["li", "followed by a set of square brackets, containing the ", ["code", "alt"], "\u000aattribute text for the image;"], + ["li", "followed by a set of parentheses, containing the URL or path to\u000athe image, and an optional ", ["code", "title"], " attribute enclosed in double\u000aor single quotes."]], + ["p", "Reference-style image syntax looks like this:"], + ["pre", ["code", "![Alt text][id]\u000a"]], + ["p", "Where \"id\" is the name of a defined image reference. Image references\u000aare defined using syntax identical to link references:"], + ["pre", ["code", "[id]: url/to/image \"Optional title attribute\"\u000a"]], + ["p", "As of this writing, Markdown has no syntax for specifying the\u000adimensions of an image; if this is important to you, you can simply\u000ause regular HTML ", ["code", ""], " tags."], "\u000a\u000a", ["hr"], "\u000a\u000a", ["h2", { + "id": "misc" +}, +"Miscellaneous"], "\u000a\u000a", ["h3", { + "id": "autolink" +}, +"Automatic Links"], "\u000a\u000a", ["p", "Markdown supports a shortcut style for creating \"automatic\" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:"], + ["pre", ["code", "\u000a"]], + ["p", "Markdown will turn this into:"], + ["pre", ["code", "http://example.com/\u000a"]], + ["p", "Automatic links for email addresses work similarly, except that\u000aMarkdown will also perform a bit of randomized decimal and hex\u000aentity-encoding to help obscure your address from address-harvesting\u000aspambots. For example, Markdown will turn this:"], + ["pre", ["code", "\u000a"]], + ["p", "into something like this:"], + ["pre", ["code", "address@exa\u000ample.com\u000a"]], + ["p", "which will render in a browser as a clickable link to \"address@example.com\"."], + ["p", "(This sort of entity-encoding trick will indeed fool many, if not\u000amost, address-harvesting bots, but it definitely won't fool all of\u000athem. It's better than nothing, but an address published in this way\u000awill probably eventually start receiving spam.)"], "\u000a\u000a", ["h3", { + "id": "backslash" +}, +"Backslash Escapes"], "\u000a\u000a", ["p", "Markdown allows you to use backslash escapes to generate literal\u000acharacters which would otherwise have special meaning in Markdown's\u000aformatting syntax. For example, if you wanted to surround a word with\u000aliteral asterisks (instead of an HTML ", ["code", ""], " tag), you can backslashes\u000abefore the asterisks, like this:"], + ["pre", ["code", "\\*literal asterisks\\*\u000a"]], + ["p", "Markdown provides backslash escapes for the following characters:"], + ["pre", ["code", "\\ backslash\u000a` backtick\u000a* asterisk\u000a_ underscore\u000a{} curly braces\u000a[] square brackets\u000a() parentheses\u000a# hash mark\u000a+ plus sign\u000a- minus sign (hyphen)\u000a. dot\u000a! exclamation mark\u000a"]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Syntax.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Syntax.text new file mode 100644 index 00000000..57360a16 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Syntax.text @@ -0,0 +1,888 @@ +Markdown: Syntax +================ + + + + +* [Overview](#overview) + * [Philosophy](#philosophy) + * [Inline HTML](#html) + * [Automatic Escaping for Special Characters](#autoescape) +* [Block Elements](#block) + * [Paragraphs and Line Breaks](#p) + * [Headers](#header) + * [Blockquotes](#blockquote) + * [Lists](#list) + * [Code Blocks](#precode) + * [Horizontal Rules](#hr) +* [Span Elements](#span) + * [Links](#link) + * [Emphasis](#em) + * [Code](#code) + * [Images](#img) +* [Miscellaneous](#misc) + * [Backslash Escapes](#backslash) + * [Automatic Links](#autolink) + + +**Note:** This document is itself written using Markdown; you +can [see the source for it by adding '.text' to the URL][src]. + + [src]: /projects/markdown/syntax.text + +* * * + +

    Overview

    + +

    Philosophy

    + +Markdown is intended to be as easy-to-read and easy-to-write as is feasible. + +Readability, however, is emphasized above all else. A Markdown-formatted +document should be publishable as-is, as plain text, without looking +like it's been marked up with tags or formatting instructions. While +Markdown's syntax has been influenced by several existing text-to-HTML +filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4], +[Grutatext] [5], and [EtText] [6] -- the single biggest source of +inspiration for Markdown's syntax is the format of plain text email. + + [1]: http://docutils.sourceforge.net/mirror/setext.html + [2]: http://www.aaronsw.com/2002/atx/ + [3]: http://textism.com/tools/textile/ + [4]: http://docutils.sourceforge.net/rst.html + [5]: http://www.triptico.com/software/grutatxt.html + [6]: http://ettext.taint.org/doc/ + +To this end, Markdown's syntax is comprised entirely of punctuation +characters, which punctuation characters have been carefully chosen so +as to look like what they mean. E.g., asterisks around a word actually +look like \*emphasis\*. Markdown lists look like, well, lists. Even +blockquotes look like quoted passages of text, assuming you've ever +used email. + + + +

    Inline HTML

    + +Markdown's syntax is intended for one purpose: to be used as a +format for *writing* for the web. + +Markdown is not a replacement for HTML, or even close to it. Its +syntax is very small, corresponding only to a very small subset of +HTML tags. The idea is *not* to create a syntax that makes it easier +to insert HTML tags. In my opinion, HTML tags are already easy to +insert. The idea for Markdown is to make it easy to read, write, and +edit prose. HTML is a *publishing* format; Markdown is a *writing* +format. Thus, Markdown's formatting syntax only addresses issues that +can be conveyed in plain text. + +For any markup that is not covered by Markdown's syntax, you simply +use HTML itself. There's no need to preface it or delimit it to +indicate that you're switching from Markdown to HTML; you just use +the tags. + +The only restrictions are that block-level HTML elements -- e.g. `
    `, +``, `
    `, `

    `, etc. -- must be separated from surrounding +content by blank lines, and the start and end tags of the block should +not be indented with tabs or spaces. Markdown is smart enough not +to add extra (unwanted) `

    ` tags around HTML block-level tags. + +For example, to add an HTML table to a Markdown article: + + This is a regular paragraph. + +

    + + + +
    Foo
    + + This is another regular paragraph. + +Note that Markdown formatting syntax is not processed within block-level +HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an +HTML block. + +Span-level HTML tags -- e.g. ``, ``, or `` -- can be +used anywhere in a Markdown paragraph, list item, or header. If you +want, you can even use HTML tags instead of Markdown formatting; e.g. if +you'd prefer to use HTML `` or `` tags instead of Markdown's +link or image syntax, go right ahead. + +Unlike block-level HTML tags, Markdown syntax *is* processed within +span-level tags. + + +

    Automatic Escaping for Special Characters

    + +In HTML, there are two characters that demand special treatment: `<` +and `&`. Left angle brackets are used to start tags; ampersands are +used to denote HTML entities. If you want to use them as literal +characters, you must escape them as entities, e.g. `<`, and +`&`. + +Ampersands in particular are bedeviling for web writers. If you want to +write about 'AT&T', you need to write '`AT&T`'. You even need to +escape ampersands within URLs. Thus, if you want to link to: + + http://images.google.com/images?num=30&q=larry+bird + +you need to encode the URL as: + + http://images.google.com/images?num=30&q=larry+bird + +in your anchor tag `href` attribute. Needless to say, this is easy to +forget, and is probably the single most common source of HTML validation +errors in otherwise well-marked-up web sites. + +Markdown allows you to use these characters naturally, taking care of +all the necessary escaping for you. If you use an ampersand as part of +an HTML entity, it remains unchanged; otherwise it will be translated +into `&`. + +So, if you want to include a copyright symbol in your article, you can write: + + © + +and Markdown will leave it alone. But if you write: + + AT&T + +Markdown will translate it to: + + AT&T + +Similarly, because Markdown supports [inline HTML](#html), if you use +angle brackets as delimiters for HTML tags, Markdown will treat them as +such. But if you write: + + 4 < 5 + +Markdown will translate it to: + + 4 < 5 + +However, inside Markdown code spans and blocks, angle brackets and +ampersands are *always* encoded automatically. This makes it easy to use +Markdown to write about HTML code. (As opposed to raw HTML, which is a +terrible format for writing about HTML syntax, because every single `<` +and `&` in your example code needs to be escaped.) + + +* * * + + +

    Block Elements

    + + +

    Paragraphs and Line Breaks

    + +A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing but spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs. + +The implication of the "one or more consecutive lines of text" rule is +that Markdown supports "hard-wrapped" text paragraphs. This differs +significantly from most other text-to-HTML formatters (including Movable +Type's "Convert Line Breaks" option) which translate every line break +character in a paragraph into a `
    ` tag. + +When you *do* want to insert a `
    ` break tag using Markdown, you +end a line with two or more spaces, then type return. + +Yes, this takes a tad more effort to create a `
    `, but a simplistic +"every line break is a `
    `" rule wouldn't work for Markdown. +Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l] +work best -- and look better -- when you format them with hard breaks. + + [bq]: #blockquote + [l]: #list + + + + + +Markdown supports two styles of headers, [Setext] [1] and [atx] [2]. + +Setext-style headers are "underlined" using equal signs (for first-level +headers) and dashes (for second-level headers). For example: + + This is an H1 + ============= + + This is an H2 + ------------- + +Any number of underlining `=`'s or `-`'s will work. + +Atx-style headers use 1-6 hash characters at the start of the line, +corresponding to header levels 1-6. For example: + + # This is an H1 + + ## This is an H2 + + ###### This is an H6 + +Optionally, you may "close" atx-style headers. This is purely +cosmetic -- you can use this if you think it looks better. The +closing hashes don't even need to match the number of hashes +used to open the header. (The number of opening hashes +determines the header level.) : + + # This is an H1 # + + ## This is an H2 ## + + ### This is an H3 ###### + + +

    Blockquotes

    + +Markdown uses email-style `>` characters for blockquoting. If you're +familiar with quoting passages of text in an email message, then you +know how to create a blockquote in Markdown. It looks best if you hard +wrap the text and put a `>` before every line: + + > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, + > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. + > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + > + > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse + > id sem consectetuer libero luctus adipiscing. + +Markdown allows you to be lazy and only put the `>` before the first +line of a hard-wrapped paragraph: + + > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, + consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. + Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + + > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse + id sem consectetuer libero luctus adipiscing. + +Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by +adding additional levels of `>`: + + > This is the first level of quoting. + > + > > This is nested blockquote. + > + > Back to the first level. + +Blockquotes can contain other Markdown elements, including headers, lists, +and code blocks: + + > ## This is a header. + > + > 1. This is the first list item. + > 2. This is the second list item. + > + > Here's some example code: + > + > return shell_exec("echo $input | $markdown_script"); + +Any decent text editor should make email-style quoting easy. For +example, with BBEdit, you can make a selection and choose Increase +Quote Level from the Text menu. + + +

    Lists

    + +Markdown supports ordered (numbered) and unordered (bulleted) lists. + +Unordered lists use asterisks, pluses, and hyphens -- interchangably +-- as list markers: + + * Red + * Green + * Blue + +is equivalent to: + + + Red + + Green + + Blue + +and: + + - Red + - Green + - Blue + +Ordered lists use numbers followed by periods: + + 1. Bird + 2. McHale + 3. Parish + +It's important to note that the actual numbers you use to mark the +list have no effect on the HTML output Markdown produces. The HTML +Markdown produces from the above list is: + +
      +
    1. Bird
    2. +
    3. McHale
    4. +
    5. Parish
    6. +
    + +If you instead wrote the list in Markdown like this: + + 1. Bird + 1. McHale + 1. Parish + +or even: + + 3. Bird + 1. McHale + 8. Parish + +you'd get the exact same HTML output. The point is, if you want to, +you can use ordinal numbers in your ordered Markdown lists, so that +the numbers in your source match the numbers in your published HTML. +But if you want to be lazy, you don't have to. + +If you do use lazy list numbering, however, you should still start the +list with the number 1. At some point in the future, Markdown may support +starting ordered lists at an arbitrary number. + +List markers typically start at the left margin, but may be indented by +up to three spaces. List markers must be followed by one or more spaces +or a tab. + +To make lists look nice, you can wrap items with hanging indents: + + * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, + viverra nec, fringilla in, laoreet vitae, risus. + * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. + +But if you want to be lazy, you don't have to: + + * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, + viverra nec, fringilla in, laoreet vitae, risus. + * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. + +If list items are separated by blank lines, Markdown will wrap the +items in `

    ` tags in the HTML output. For example, this input: + + * Bird + * Magic + +will turn into: + +

      +
    • Bird
    • +
    • Magic
    • +
    + +But this: + + * Bird + + * Magic + +will turn into: + +
      +
    • Bird

    • +
    • Magic

    • +
    + +List items may consist of multiple paragraphs. Each subsequent +paragraph in a list item must be intended by either 4 spaces +or one tab: + + 1. This is a list item with two paragraphs. Lorem ipsum dolor + sit amet, consectetuer adipiscing elit. Aliquam hendrerit + mi posuere lectus. + + Vestibulum enim wisi, viverra nec, fringilla in, laoreet + vitae, risus. Donec sit amet nisl. Aliquam semper ipsum + sit amet velit. + + 2. Suspendisse id sem consectetuer libero luctus adipiscing. + +It looks nice if you indent every line of the subsequent +paragraphs, but here again, Markdown will allow you to be +lazy: + + * This is a list item with two paragraphs. + + This is the second paragraph in the list item. You're + only required to indent the first line. Lorem ipsum dolor + sit amet, consectetuer adipiscing elit. + + * Another item in the same list. + +To put a blockquote within a list item, the blockquote's `>` +delimiters need to be indented: + + * A list item with a blockquote: + + > This is a blockquote + > inside a list item. + +To put a code block within a list item, the code block needs +to be indented *twice* -- 8 spaces or two tabs: + + * A list item with a code block: + + + + +It's worth noting that it's possible to trigger an ordered list by +accident, by writing something like this: + + 1986. What a great season. + +In other words, a *number-period-space* sequence at the beginning of a +line. To avoid this, you can backslash-escape the period: + + 1986\. What a great season. + + + +

    Code Blocks

    + +Pre-formatted code blocks are used for writing about programming or +markup source code. Rather than forming normal paragraphs, the lines +of a code block are interpreted literally. Markdown wraps a code block +in both `
    ` and `` tags.
    +
    +To produce a code block in Markdown, simply indent every line of the
    +block by at least 4 spaces or 1 tab. For example, given this input:
    +
    +    This is a normal paragraph:
    +
    +        This is a code block.
    +
    +Markdown will generate:
    +
    +    

    This is a normal paragraph:

    + +
    This is a code block.
    +    
    + +One level of indentation -- 4 spaces or 1 tab -- is removed from each +line of the code block. For example, this: + + Here is an example of AppleScript: + + tell application "Foo" + beep + end tell + +will turn into: + +

    Here is an example of AppleScript:

    + +
    tell application "Foo"
    +        beep
    +    end tell
    +    
    + +A code block continues until it reaches a line that is not indented +(or the end of the article). + +Within a code block, ampersands (`&`) and angle brackets (`<` and `>`) +are automatically converted into HTML entities. This makes it very +easy to include example HTML source code using Markdown -- just paste +it and indent it, and Markdown will handle the hassle of encoding the +ampersands and angle brackets. For example, this: + + + +will turn into: + +
    <div class="footer">
    +        &copy; 2004 Foo Corporation
    +    </div>
    +    
    + +Regular Markdown syntax is not processed within code blocks. E.g., +asterisks are just literal asterisks within a code block. This means +it's also easy to use Markdown to write about Markdown's own syntax. + + + +

    Horizontal Rules

    + +You can produce a horizontal rule tag (`
    `) by placing three or +more hyphens, asterisks, or underscores on a line by themselves. If you +wish, you may use spaces between the hyphens or asterisks. Each of the +following lines will produce a horizontal rule: + + * * * + + *** + + ***** + + - - - + + --------------------------------------- + + _ _ _ + + +* * * + +

    Span Elements

    + + + +Markdown supports two style of links: *inline* and *reference*. + +In both styles, the link text is delimited by [square brackets]. + +To create an inline link, use a set of regular parentheses immediately +after the link text's closing square bracket. Inside the parentheses, +put the URL where you want the link to point, along with an *optional* +title for the link, surrounded in quotes. For example: + + This is [an example](http://example.com/ "Title") inline link. + + [This link](http://example.net/) has no title attribute. + +Will produce: + +

    This is + an example inline link.

    + +

    This link has no + title attribute.

    + +If you're referring to a local resource on the same server, you can +use relative paths: + + See my [About](/about/) page for details. + +Reference-style links use a second set of square brackets, inside +which you place a label of your choosing to identify the link: + + This is [an example][id] reference-style link. + +You can optionally use a space to separate the sets of brackets: + + This is [an example] [id] reference-style link. + +Then, anywhere in the document, you define your link label like this, +on a line by itself: + + [id]: http://example.com/ "Optional Title Here" + +That is: + +* Square brackets containing the link identifier (optionally + indented from the left margin using up to three spaces); +* followed by a colon; +* followed by one or more spaces (or tabs); +* followed by the URL for the link; +* optionally followed by a title attribute for the link, enclosed + in double or single quotes. + +The link URL may, optionally, be surrounded by angle brackets: + + [id]: "Optional Title Here" + +You can put the title attribute on the next line and use extra spaces +or tabs for padding, which tends to look better with longer URLs: + + [id]: http://example.com/longish/path/to/resource/here + "Optional Title Here" + +Link definitions are only used for creating links during Markdown +processing, and are stripped from your document in the HTML output. + +Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links: + + [link text][a] + [link text][A] + +are equivalent. + +The *implicit link name* shortcut allows you to omit the name of the +link, in which case the link text itself is used as the name. +Just use an empty set of square brackets -- e.g., to link the word +"Google" to the google.com web site, you could simply write: + + [Google][] + +And then define the link: + + [Google]: http://google.com/ + +Because link names may contain spaces, this shortcut even works for +multiple words in the link text: + + Visit [Daring Fireball][] for more information. + +And then define the link: + + [Daring Fireball]: http://daringfireball.net/ + +Link definitions can be placed anywhere in your Markdown document. I +tend to put them immediately after each paragraph in which they're +used, but if you want, you can put them all at the end of your +document, sort of like footnotes. + +Here's an example of reference links in action: + + I get 10 times more traffic from [Google] [1] than from + [Yahoo] [2] or [MSN] [3]. + + [1]: http://google.com/ "Google" + [2]: http://search.yahoo.com/ "Yahoo Search" + [3]: http://search.msn.com/ "MSN Search" + +Using the implicit link name shortcut, you could instead write: + + I get 10 times more traffic from [Google][] than from + [Yahoo][] or [MSN][]. + + [google]: http://google.com/ "Google" + [yahoo]: http://search.yahoo.com/ "Yahoo Search" + [msn]: http://search.msn.com/ "MSN Search" + +Both of the above examples will produce the following HTML output: + +

    I get 10 times more traffic from Google than from + Yahoo + or MSN.

    + +For comparison, here is the same paragraph written using +Markdown's inline link style: + + I get 10 times more traffic from [Google](http://google.com/ "Google") + than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or + [MSN](http://search.msn.com/ "MSN Search"). + +The point of reference-style links is not that they're easier to +write. The point is that with reference-style links, your document +source is vastly more readable. Compare the above examples: using +reference-style links, the paragraph itself is only 81 characters +long; with inline-style links, it's 176 characters; and as raw HTML, +it's 234 characters. In the raw HTML, there's more markup than there +is text. + +With Markdown's reference-style links, a source document much more +closely resembles the final output, as rendered in a browser. By +allowing you to move the markup-related metadata out of the paragraph, +you can add links without interrupting the narrative flow of your +prose. + + +

    Emphasis

    + +Markdown treats asterisks (`*`) and underscores (`_`) as indicators of +emphasis. Text wrapped with one `*` or `_` will be wrapped with an +HTML `` tag; double `*`'s or `_`'s will be wrapped with an HTML +`` tag. E.g., this input: + + *single asterisks* + + _single underscores_ + + **double asterisks** + + __double underscores__ + +will produce: + + single asterisks + + single underscores + + double asterisks + + double underscores + +You can use whichever style you prefer; the lone restriction is that +the same character must be used to open and close an emphasis span. + +Emphasis can be used in the middle of a word: + + un*fucking*believable + +But if you surround an `*` or `_` with spaces, it'll be treated as a +literal asterisk or underscore. + +To produce a literal asterisk or underscore at a position where it +would otherwise be used as an emphasis delimiter, you can backslash +escape it: + + \*this text is surrounded by literal asterisks\* + + + +

    Code

    + +To indicate a span of code, wrap it with backtick quotes (`` ` ``). +Unlike a pre-formatted code block, a code span indicates code within a +normal paragraph. For example: + + Use the `printf()` function. + +will produce: + +

    Use the printf() function.

    + +To include a literal backtick character within a code span, you can use +multiple backticks as the opening and closing delimiters: + + ``There is a literal backtick (`) here.`` + +which will produce this: + +

    There is a literal backtick (`) here.

    + +The backtick delimiters surrounding a code span may include spaces -- +one after the opening, one before the closing. This allows you to place +literal backtick characters at the beginning or end of a code span: + + A single backtick in a code span: `` ` `` + + A backtick-delimited string in a code span: `` `foo` `` + +will produce: + +

    A single backtick in a code span: `

    + +

    A backtick-delimited string in a code span: `foo`

    + +With a code span, ampersands and angle brackets are encoded as HTML +entities automatically, which makes it easy to include example HTML +tags. Markdown will turn this: + + Please don't use any `` tags. + +into: + +

    Please don't use any <blink> tags.

    + +You can write this: + + `—` is the decimal-encoded equivalent of `—`. + +to produce: + +

    &#8212; is the decimal-encoded + equivalent of &mdash;.

    + + + +

    Images

    + +Admittedly, it's fairly difficult to devise a "natural" syntax for +placing images into a plain text document format. + +Markdown uses an image syntax that is intended to resemble the syntax +for links, allowing for two styles: *inline* and *reference*. + +Inline image syntax looks like this: + + ![Alt text](/path/to/img.jpg) + + ![Alt text](/path/to/img.jpg "Optional title") + +That is: + +* An exclamation mark: `!`; +* followed by a set of square brackets, containing the `alt` + attribute text for the image; +* followed by a set of parentheses, containing the URL or path to + the image, and an optional `title` attribute enclosed in double + or single quotes. + +Reference-style image syntax looks like this: + + ![Alt text][id] + +Where "id" is the name of a defined image reference. Image references +are defined using syntax identical to link references: + + [id]: url/to/image "Optional title attribute" + +As of this writing, Markdown has no syntax for specifying the +dimensions of an image; if this is important to you, you can simply +use regular HTML `` tags. + + +* * * + + +

    Miscellaneous

    + + + +Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this: + + + +Markdown will turn this into: + + http://example.com/ + +Automatic links for email addresses work similarly, except that +Markdown will also perform a bit of randomized decimal and hex +entity-encoding to help obscure your address from address-harvesting +spambots. For example, Markdown will turn this: + + + +into something like this: + + address@exa + mple.com + +which will render in a browser as a clickable link to "address@example.com". + +(This sort of entity-encoding trick will indeed fool many, if not +most, address-harvesting bots, but it definitely won't fool all of +them. It's better than nothing, but an address published in this way +will probably eventually start receiving spam.) + + + +

    Backslash Escapes

    + +Markdown allows you to use backslash escapes to generate literal +characters which would otherwise have special meaning in Markdown's +formatting syntax. For example, if you wanted to surround a word with +literal asterisks (instead of an HTML `` tag), you can backslashes +before the asterisks, like this: + + \*literal asterisks\* + +Markdown provides backslash escapes for the following characters: + + \ backslash + ` backtick + * asterisk + _ underscore + {} curly braces + [] square brackets + () parentheses + # hash mark + + plus sign + - minus sign (hyphen) + . dot + ! exclamation mark + diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Syntax.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Syntax.xhtml new file mode 100644 index 00000000..5c01306c --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Markdown_Documentation_-_Syntax.xhtml @@ -0,0 +1,942 @@ +

    Markdown: Syntax

    + + + + + +

    Note: This document is itself written using Markdown; you +can see the source for it by adding '.text' to the URL.

    + +
    + +

    Overview

    + +

    Philosophy

    + +

    Markdown is intended to be as easy-to-read and easy-to-write as is feasible.

    + +

    Readability, however, is emphasized above all else. A Markdown-formatted +document should be publishable as-is, as plain text, without looking +like it's been marked up with tags or formatting instructions. While +Markdown's syntax has been influenced by several existing text-to-HTML +filters -- including Setext, atx, Textile, reStructuredText, +Grutatext, and EtText -- the single biggest source of +inspiration for Markdown's syntax is the format of plain text email.

    + +

    To this end, Markdown's syntax is comprised entirely of punctuation +characters, which punctuation characters have been carefully chosen so +as to look like what they mean. E.g., asterisks around a word actually +look like *emphasis*. Markdown lists look like, well, lists. Even +blockquotes look like quoted passages of text, assuming you've ever +used email.

    + +

    Inline HTML

    + +

    Markdown's syntax is intended for one purpose: to be used as a +format for writing for the web.

    + +

    Markdown is not a replacement for HTML, or even close to it. Its +syntax is very small, corresponding only to a very small subset of +HTML tags. The idea is not to create a syntax that makes it easier +to insert HTML tags. In my opinion, HTML tags are already easy to +insert. The idea for Markdown is to make it easy to read, write, and +edit prose. HTML is a publishing format; Markdown is a writing +format. Thus, Markdown's formatting syntax only addresses issues that +can be conveyed in plain text.

    + +

    For any markup that is not covered by Markdown's syntax, you simply +use HTML itself. There's no need to preface it or delimit it to +indicate that you're switching from Markdown to HTML; you just use +the tags.

    + +

    The only restrictions are that block-level HTML elements -- e.g. <div>, +<table>, <pre>, <p>, etc. -- must be separated from surrounding +content by blank lines, and the start and end tags of the block should +not be indented with tabs or spaces. Markdown is smart enough not +to add extra (unwanted) <p> tags around HTML block-level tags.

    + +

    For example, to add an HTML table to a Markdown article:

    + +
    This is a regular paragraph.
    +
    +<table>
    +    <tr>
    +        <td>Foo</td>
    +    </tr>
    +</table>
    +
    +This is another regular paragraph.
    +
    + +

    Note that Markdown formatting syntax is not processed within block-level +HTML tags. E.g., you can't use Markdown-style *emphasis* inside an +HTML block.

    + +

    Span-level HTML tags -- e.g. <span>, <cite>, or <del> -- can be +used anywhere in a Markdown paragraph, list item, or header. If you +want, you can even use HTML tags instead of Markdown formatting; e.g. if +you'd prefer to use HTML <a> or <img> tags instead of Markdown's +link or image syntax, go right ahead.

    + +

    Unlike block-level HTML tags, Markdown syntax is processed within +span-level tags.

    + +

    Automatic Escaping for Special Characters

    + +

    In HTML, there are two characters that demand special treatment: < +and &. Left angle brackets are used to start tags; ampersands are +used to denote HTML entities. If you want to use them as literal +characters, you must escape them as entities, e.g. &lt;, and +&amp;.

    + +

    Ampersands in particular are bedeviling for web writers. If you want to +write about 'AT&T', you need to write 'AT&amp;T'. You even need to +escape ampersands within URLs. Thus, if you want to link to:

    + +
    http://images.google.com/images?num=30&q=larry+bird
    +
    + +

    you need to encode the URL as:

    + +
    http://images.google.com/images?num=30&amp;q=larry+bird
    +
    + +

    in your anchor tag href attribute. Needless to say, this is easy to +forget, and is probably the single most common source of HTML validation +errors in otherwise well-marked-up web sites.

    + +

    Markdown allows you to use these characters naturally, taking care of +all the necessary escaping for you. If you use an ampersand as part of +an HTML entity, it remains unchanged; otherwise it will be translated +into &amp;.

    + +

    So, if you want to include a copyright symbol in your article, you can write:

    + +
    &copy;
    +
    + +

    and Markdown will leave it alone. But if you write:

    + +
    AT&T
    +
    + +

    Markdown will translate it to:

    + +
    AT&amp;T
    +
    + +

    Similarly, because Markdown supports inline HTML, if you use +angle brackets as delimiters for HTML tags, Markdown will treat them as +such. But if you write:

    + +
    4 < 5
    +
    + +

    Markdown will translate it to:

    + +
    4 &lt; 5
    +
    + +

    However, inside Markdown code spans and blocks, angle brackets and +ampersands are always encoded automatically. This makes it easy to use +Markdown to write about HTML code. (As opposed to raw HTML, which is a +terrible format for writing about HTML syntax, because every single < +and & in your example code needs to be escaped.)

    + +
    + +

    Block Elements

    + +

    Paragraphs and Line Breaks

    + +

    A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing but spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs.

    + +

    The implication of the "one or more consecutive lines of text" rule is +that Markdown supports "hard-wrapped" text paragraphs. This differs +significantly from most other text-to-HTML formatters (including Movable +Type's "Convert Line Breaks" option) which translate every line break +character in a paragraph into a <br /> tag.

    + +

    When you do want to insert a <br /> break tag using Markdown, you +end a line with two or more spaces, then type return.

    + +

    Yes, this takes a tad more effort to create a <br />, but a simplistic +"every line break is a <br />" rule wouldn't work for Markdown. +Markdown's email-style blockquoting and multi-paragraph list items +work best -- and look better -- when you format them with hard breaks.

    + + + +

    Markdown supports two styles of headers, Setext and atx.

    + +

    Setext-style headers are "underlined" using equal signs (for first-level +headers) and dashes (for second-level headers). For example:

    + +
    This is an H1
    +=============
    +
    +This is an H2
    +-------------
    +
    + +

    Any number of underlining ='s or -'s will work.

    + +

    Atx-style headers use 1-6 hash characters at the start of the line, +corresponding to header levels 1-6. For example:

    + +
    # This is an H1
    +
    +## This is an H2
    +
    +###### This is an H6
    +
    + +

    Optionally, you may "close" atx-style headers. This is purely +cosmetic -- you can use this if you think it looks better. The +closing hashes don't even need to match the number of hashes +used to open the header. (The number of opening hashes +determines the header level.) :

    + +
    # This is an H1 #
    +
    +## This is an H2 ##
    +
    +### This is an H3 ######
    +
    + +

    Blockquotes

    + +

    Markdown uses email-style > characters for blockquoting. If you're +familiar with quoting passages of text in an email message, then you +know how to create a blockquote in Markdown. It looks best if you hard +wrap the text and put a > before every line:

    + +
    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
    +> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
    +> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
    +> 
    +> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
    +> id sem consectetuer libero luctus adipiscing.
    +
    + +

    Markdown allows you to be lazy and only put the > before the first +line of a hard-wrapped paragraph:

    + +
    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
    +consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
    +Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
    +
    +> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
    +id sem consectetuer libero luctus adipiscing.
    +
    + +

    Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by +adding additional levels of >:

    + +
    > This is the first level of quoting.
    +>
    +> > This is nested blockquote.
    +>
    +> Back to the first level.
    +
    + +

    Blockquotes can contain other Markdown elements, including headers, lists, +and code blocks:

    + +
    > ## This is a header.
    +> 
    +> 1.   This is the first list item.
    +> 2.   This is the second list item.
    +> 
    +> Here's some example code:
    +> 
    +>     return shell_exec("echo $input | $markdown_script");
    +
    + +

    Any decent text editor should make email-style quoting easy. For +example, with BBEdit, you can make a selection and choose Increase +Quote Level from the Text menu.

    + +

    Lists

    + +

    Markdown supports ordered (numbered) and unordered (bulleted) lists.

    + +

    Unordered lists use asterisks, pluses, and hyphens -- interchangably +-- as list markers:

    + +
    *   Red
    +*   Green
    +*   Blue
    +
    + +

    is equivalent to:

    + +
    +   Red
    ++   Green
    ++   Blue
    +
    + +

    and:

    + +
    -   Red
    +-   Green
    +-   Blue
    +
    + +

    Ordered lists use numbers followed by periods:

    + +
    1.  Bird
    +2.  McHale
    +3.  Parish
    +
    + +

    It's important to note that the actual numbers you use to mark the +list have no effect on the HTML output Markdown produces. The HTML +Markdown produces from the above list is:

    + +
    <ol>
    +<li>Bird</li>
    +<li>McHale</li>
    +<li>Parish</li>
    +</ol>
    +
    + +

    If you instead wrote the list in Markdown like this:

    + +
    1.  Bird
    +1.  McHale
    +1.  Parish
    +
    + +

    or even:

    + +
    3. Bird
    +1. McHale
    +8. Parish
    +
    + +

    you'd get the exact same HTML output. The point is, if you want to, +you can use ordinal numbers in your ordered Markdown lists, so that +the numbers in your source match the numbers in your published HTML. +But if you want to be lazy, you don't have to.

    + +

    If you do use lazy list numbering, however, you should still start the +list with the number 1. At some point in the future, Markdown may support +starting ordered lists at an arbitrary number.

    + +

    List markers typically start at the left margin, but may be indented by +up to three spaces. List markers must be followed by one or more spaces +or a tab.

    + +

    To make lists look nice, you can wrap items with hanging indents:

    + +
    *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    +    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
    +    viverra nec, fringilla in, laoreet vitae, risus.
    +*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
    +    Suspendisse id sem consectetuer libero luctus adipiscing.
    +
    + +

    But if you want to be lazy, you don't have to:

    + +
    *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    +Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
    +viverra nec, fringilla in, laoreet vitae, risus.
    +*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
    +Suspendisse id sem consectetuer libero luctus adipiscing.
    +
    + +

    If list items are separated by blank lines, Markdown will wrap the +items in <p> tags in the HTML output. For example, this input:

    + +
    *   Bird
    +*   Magic
    +
    + +

    will turn into:

    + +
    <ul>
    +<li>Bird</li>
    +<li>Magic</li>
    +</ul>
    +
    + +

    But this:

    + +
    *   Bird
    +
    +*   Magic
    +
    + +

    will turn into:

    + +
    <ul>
    +<li><p>Bird</p></li>
    +<li><p>Magic</p></li>
    +</ul>
    +
    + +

    List items may consist of multiple paragraphs. Each subsequent +paragraph in a list item must be intended by either 4 spaces +or one tab:

    + +
    1.  This is a list item with two paragraphs. Lorem ipsum dolor
    +    sit amet, consectetuer adipiscing elit. Aliquam hendrerit
    +    mi posuere lectus.
    +
    +    Vestibulum enim wisi, viverra nec, fringilla in, laoreet
    +    vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
    +    sit amet velit.
    +
    +2.  Suspendisse id sem consectetuer libero luctus adipiscing.
    +
    + +

    It looks nice if you indent every line of the subsequent +paragraphs, but here again, Markdown will allow you to be +lazy:

    + +
    *   This is a list item with two paragraphs.
    +
    +    This is the second paragraph in the list item. You're
    +only required to indent the first line. Lorem ipsum dolor
    +sit amet, consectetuer adipiscing elit.
    +
    +*   Another item in the same list.
    +
    + +

    To put a blockquote within a list item, the blockquote's > +delimiters need to be indented:

    + +
    *   A list item with a blockquote:
    +
    +    > This is a blockquote
    +    > inside a list item.
    +
    + +

    To put a code block within a list item, the code block needs +to be indented twice -- 8 spaces or two tabs:

    + +
    *   A list item with a code block:
    +
    +        <code goes here>
    +
    + +

    It's worth noting that it's possible to trigger an ordered list by +accident, by writing something like this:

    + +
    1986. What a great season.
    +
    + +

    In other words, a number-period-space sequence at the beginning of a +line. To avoid this, you can backslash-escape the period:

    + +
    1986\. What a great season.
    +
    + +

    Code Blocks

    + +

    Pre-formatted code blocks are used for writing about programming or +markup source code. Rather than forming normal paragraphs, the lines +of a code block are interpreted literally. Markdown wraps a code block +in both <pre> and <code> tags.

    + +

    To produce a code block in Markdown, simply indent every line of the +block by at least 4 spaces or 1 tab. For example, given this input:

    + +
    This is a normal paragraph:
    +
    +    This is a code block.
    +
    + +

    Markdown will generate:

    + +
    <p>This is a normal paragraph:</p>
    +
    +<pre><code>This is a code block.
    +</code></pre>
    +
    + +

    One level of indentation -- 4 spaces or 1 tab -- is removed from each +line of the code block. For example, this:

    + +
    Here is an example of AppleScript:
    +
    +    tell application "Foo"
    +        beep
    +    end tell
    +
    + +

    will turn into:

    + +
    <p>Here is an example of AppleScript:</p>
    +
    +<pre><code>tell application "Foo"
    +    beep
    +end tell
    +</code></pre>
    +
    + +

    A code block continues until it reaches a line that is not indented +(or the end of the article).

    + +

    Within a code block, ampersands (&) and angle brackets (< and >) +are automatically converted into HTML entities. This makes it very +easy to include example HTML source code using Markdown -- just paste +it and indent it, and Markdown will handle the hassle of encoding the +ampersands and angle brackets. For example, this:

    + +
        <div class="footer">
    +        &copy; 2004 Foo Corporation
    +    </div>
    +
    + +

    will turn into:

    + +
    <pre><code>&lt;div class="footer"&gt;
    +    &amp;copy; 2004 Foo Corporation
    +&lt;/div&gt;
    +</code></pre>
    +
    + +

    Regular Markdown syntax is not processed within code blocks. E.g., +asterisks are just literal asterisks within a code block. This means +it's also easy to use Markdown to write about Markdown's own syntax.

    + +

    Horizontal Rules

    + +

    You can produce a horizontal rule tag (<hr />) by placing three or +more hyphens, asterisks, or underscores on a line by themselves. If you +wish, you may use spaces between the hyphens or asterisks. Each of the +following lines will produce a horizontal rule:

    + +
    * * *
    +
    +***
    +
    +*****
    +
    +- - -
    +
    +---------------------------------------
    +
    +_ _ _
    +
    + +
    + +

    Span Elements

    + + + +

    Markdown supports two style of links: inline and reference.

    + +

    In both styles, the link text is delimited by [square brackets].

    + +

    To create an inline link, use a set of regular parentheses immediately +after the link text's closing square bracket. Inside the parentheses, +put the URL where you want the link to point, along with an optional +title for the link, surrounded in quotes. For example:

    + +
    This is [an example](http://example.com/ "Title") inline link.
    +
    +[This link](http://example.net/) has no title attribute.
    +
    + +

    Will produce:

    + +
    <p>This is <a href="http://example.com/" title="Title">
    +an example</a> inline link.</p>
    +
    +<p><a href="http://example.net/">This link</a> has no
    +title attribute.</p>
    +
    + +

    If you're referring to a local resource on the same server, you can +use relative paths:

    + +
    See my [About](/about/) page for details.
    +
    + +

    Reference-style links use a second set of square brackets, inside +which you place a label of your choosing to identify the link:

    + +
    This is [an example][id] reference-style link.
    +
    + +

    You can optionally use a space to separate the sets of brackets:

    + +
    This is [an example] [id] reference-style link.
    +
    + +

    Then, anywhere in the document, you define your link label like this, +on a line by itself:

    + +
    [id]: http://example.com/  "Optional Title Here"
    +
    + +

    That is:

    + +
      +
    • Square brackets containing the link identifier (optionally +indented from the left margin using up to three spaces);
    • +
    • followed by a colon;
    • +
    • followed by one or more spaces (or tabs);
    • +
    • followed by the URL for the link;
    • +
    • optionally followed by a title attribute for the link, enclosed +in double or single quotes.
    • +
    + +

    The link URL may, optionally, be surrounded by angle brackets:

    + +
    [id]: <http://example.com/>  "Optional Title Here"
    +
    + +

    You can put the title attribute on the next line and use extra spaces +or tabs for padding, which tends to look better with longer URLs:

    + +
    [id]: http://example.com/longish/path/to/resource/here
    +    "Optional Title Here"
    +
    + +

    Link definitions are only used for creating links during Markdown +processing, and are stripped from your document in the HTML output.

    + +

    Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are not case sensitive. E.g. these two links:

    + +
    [link text][a]
    +[link text][A]
    +
    + +

    are equivalent.

    + +

    The implicit link name shortcut allows you to omit the name of the +link, in which case the link text itself is used as the name. +Just use an empty set of square brackets -- e.g., to link the word +"Google" to the google.com web site, you could simply write:

    + +
    [Google][]
    +
    + +

    And then define the link:

    + +
    [Google]: http://google.com/
    +
    + +

    Because link names may contain spaces, this shortcut even works for +multiple words in the link text:

    + +
    Visit [Daring Fireball][] for more information.
    +
    + +

    And then define the link:

    + +
    [Daring Fireball]: http://daringfireball.net/
    +
    + +

    Link definitions can be placed anywhere in your Markdown document. I +tend to put them immediately after each paragraph in which they're +used, but if you want, you can put them all at the end of your +document, sort of like footnotes.

    + +

    Here's an example of reference links in action:

    + +
    I get 10 times more traffic from [Google] [1] than from
    +[Yahoo] [2] or [MSN] [3].
    +
    +  [1]: http://google.com/        "Google"
    +  [2]: http://search.yahoo.com/  "Yahoo Search"
    +  [3]: http://search.msn.com/    "MSN Search"
    +
    + +

    Using the implicit link name shortcut, you could instead write:

    + +
    I get 10 times more traffic from [Google][] than from
    +[Yahoo][] or [MSN][].
    +
    +  [google]: http://google.com/        "Google"
    +  [yahoo]:  http://search.yahoo.com/  "Yahoo Search"
    +  [msn]:    http://search.msn.com/    "MSN Search"
    +
    + +

    Both of the above examples will produce the following HTML output:

    + +
    <p>I get 10 times more traffic from <a href="http://google.com/"
    +title="Google">Google</a> than from
    +<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
    +or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
    +
    + +

    For comparison, here is the same paragraph written using +Markdown's inline link style:

    + +
    I get 10 times more traffic from [Google](http://google.com/ "Google")
    +than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
    +[MSN](http://search.msn.com/ "MSN Search").
    +
    + +

    The point of reference-style links is not that they're easier to +write. The point is that with reference-style links, your document +source is vastly more readable. Compare the above examples: using +reference-style links, the paragraph itself is only 81 characters +long; with inline-style links, it's 176 characters; and as raw HTML, +it's 234 characters. In the raw HTML, there's more markup than there +is text.

    + +

    With Markdown's reference-style links, a source document much more +closely resembles the final output, as rendered in a browser. By +allowing you to move the markup-related metadata out of the paragraph, +you can add links without interrupting the narrative flow of your +prose.

    + +

    Emphasis

    + +

    Markdown treats asterisks (*) and underscores (_) as indicators of +emphasis. Text wrapped with one * or _ will be wrapped with an +HTML <em> tag; double *'s or _'s will be wrapped with an HTML +<strong> tag. E.g., this input:

    + +
    *single asterisks*
    +
    +_single underscores_
    +
    +**double asterisks**
    +
    +__double underscores__
    +
    + +

    will produce:

    + +
    <em>single asterisks</em>
    +
    +<em>single underscores</em>
    +
    +<strong>double asterisks</strong>
    +
    +<strong>double underscores</strong>
    +
    + +

    You can use whichever style you prefer; the lone restriction is that +the same character must be used to open and close an emphasis span.

    + +

    Emphasis can be used in the middle of a word:

    + +
    un*fucking*believable
    +
    + +

    But if you surround an * or _ with spaces, it'll be treated as a +literal asterisk or underscore.

    + +

    To produce a literal asterisk or underscore at a position where it +would otherwise be used as an emphasis delimiter, you can backslash +escape it:

    + +
    \*this text is surrounded by literal asterisks\*
    +
    + +

    Code

    + +

    To indicate a span of code, wrap it with backtick quotes (`). +Unlike a pre-formatted code block, a code span indicates code within a +normal paragraph. For example:

    + +
    Use the `printf()` function.
    +
    + +

    will produce:

    + +
    <p>Use the <code>printf()</code> function.</p>
    +
    + +

    To include a literal backtick character within a code span, you can use +multiple backticks as the opening and closing delimiters:

    + +
    ``There is a literal backtick (`) here.``
    +
    + +

    which will produce this:

    + +
    <p><code>There is a literal backtick (`) here.</code></p>
    +
    + +

    The backtick delimiters surrounding a code span may include spaces -- +one after the opening, one before the closing. This allows you to place +literal backtick characters at the beginning or end of a code span:

    + +
    A single backtick in a code span: `` ` ``
    +
    +A backtick-delimited string in a code span: `` `foo` ``
    +
    + +

    will produce:

    + +
    <p>A single backtick in a code span: <code>`</code></p>
    +
    +<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
    +
    + +

    With a code span, ampersands and angle brackets are encoded as HTML +entities automatically, which makes it easy to include example HTML +tags. Markdown will turn this:

    + +
    Please don't use any `<blink>` tags.
    +
    + +

    into:

    + +
    <p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>
    +
    + +

    You can write this:

    + +
    `&#8212;` is the decimal-encoded equivalent of `&mdash;`.
    +
    + +

    to produce:

    + +
    <p><code>&amp;#8212;</code> is the decimal-encoded
    +equivalent of <code>&amp;mdash;</code>.</p>
    +
    + +

    Images

    + +

    Admittedly, it's fairly difficult to devise a "natural" syntax for +placing images into a plain text document format.

    + +

    Markdown uses an image syntax that is intended to resemble the syntax +for links, allowing for two styles: inline and reference.

    + +

    Inline image syntax looks like this:

    + +
    ![Alt text](/path/to/img.jpg)
    +
    +![Alt text](/path/to/img.jpg "Optional title")
    +
    + +

    That is:

    + +
      +
    • An exclamation mark: !;
    • +
    • followed by a set of square brackets, containing the alt +attribute text for the image;
    • +
    • followed by a set of parentheses, containing the URL or path to +the image, and an optional title attribute enclosed in double +or single quotes.
    • +
    + +

    Reference-style image syntax looks like this:

    + +
    ![Alt text][id]
    +
    + +

    Where "id" is the name of a defined image reference. Image references +are defined using syntax identical to link references:

    + +
    [id]: url/to/image  "Optional title attribute"
    +
    + +

    As of this writing, Markdown has no syntax for specifying the +dimensions of an image; if this is important to you, you can simply +use regular HTML <img> tags.

    + +
    + +

    Miscellaneous

    + + + +

    Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:

    + +
    <http://example.com/>
    +
    + +

    Markdown will turn this into:

    + +
    <a href="http://example.com/">http://example.com/</a>
    +
    + +

    Automatic links for email addresses work similarly, except that +Markdown will also perform a bit of randomized decimal and hex +entity-encoding to help obscure your address from address-harvesting +spambots. For example, Markdown will turn this:

    + +
    <address@example.com>
    +
    + +

    into something like this:

    + +
    <a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
    +&#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;
    +&#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;
    +&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>
    +
    + +

    which will render in a browser as a clickable link to "address@example.com".

    + +

    (This sort of entity-encoding trick will indeed fool many, if not +most, address-harvesting bots, but it definitely won't fool all of +them. It's better than nothing, but an address published in this way +will probably eventually start receiving spam.)

    + +

    Backslash Escapes

    + +

    Markdown allows you to use backslash escapes to generate literal +characters which would otherwise have special meaning in Markdown's +formatting syntax. For example, if you wanted to surround a word with +literal asterisks (instead of an HTML <em> tag), you can backslashes +before the asterisks, like this:

    + +
    \*literal asterisks\*
    +
    + +

    Markdown provides backslash escapes for the following characters:

    + +
    \   backslash
    +`   backtick
    +*   asterisk
    +_   underscore
    +{}  curly braces
    +[]  square brackets
    +()  parentheses
    +#   hash mark
    ++   plus sign
    +-   minus sign (hyphen)
    +.   dot
    +!   exclamation mark
    +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Nested_blockquotes.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Nested_blockquotes.json new file mode 100644 index 00000000..310ad22d --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Nested_blockquotes.json @@ -0,0 +1,3 @@ +["html", ["blockquote", ["p", "foo"], + ["blockquote", ["p", "bar"]], + ["p", "foo"]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Nested_blockquotes.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Nested_blockquotes.text new file mode 100644 index 00000000..ed3c624f --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Nested_blockquotes.text @@ -0,0 +1,5 @@ +> foo +> +> > bar +> +> foo diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Nested_blockquotes.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Nested_blockquotes.xhtml new file mode 100644 index 00000000..d8ec7f8e --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Nested_blockquotes.xhtml @@ -0,0 +1,9 @@ +
    +

    foo

    + +
    +

    bar

    +
    + +

    foo

    +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Ordered_and_unordered_lists.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Ordered_and_unordered_lists.json new file mode 100644 index 00000000..d52c6830 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Ordered_and_unordered_lists.json @@ -0,0 +1,59 @@ +["html", ["h2", "Unordered"], "\u000a\u000a", ["p", "Asterisks tight:"], + ["ul", ["li", "asterisk 1"], + ["li", "asterisk 2"], + ["li", "asterisk 3"]], + ["p", "Asterisks loose:"], + ["ul", ["li", ["p", "asterisk 1"]], + ["li", ["p", "asterisk 2"]], + ["li", ["p", "asterisk 3"]]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", "Pluses tight:"], + ["ul", ["li", "Plus 1"], + ["li", "Plus 2"], + ["li", "Plus 3"]], + ["p", "Pluses loose:"], + ["ul", ["li", ["p", "Plus 1"]], + ["li", ["p", "Plus 2"]], + ["li", ["p", "Plus 3"]]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", "Minuses tight:"], + ["ul", ["li", "Minus 1"], + ["li", "Minus 2"], + ["li", "Minus 3"]], + ["p", "Minuses loose:"], + ["ul", ["li", ["p", "Minus 1"]], + ["li", ["p", "Minus 2"]], + ["li", ["p", "Minus 3"]]], "\u000a\u000a", ["h2", "Ordered"], "\u000a\u000a", ["p", "Tight:"], + ["ol", ["li", "First"], + ["li", "Second"], + ["li", "Third"]], + ["p", "and:"], + ["ol", ["li", "One"], + ["li", "Two"], + ["li", "Three"]], + ["p", "Loose using tabs:"], + ["ol", ["li", ["p", "First"]], + ["li", ["p", "Second"]], + ["li", ["p", "Third"]]], + ["p", "and using spaces:"], + ["ol", ["li", ["p", "One"]], + ["li", ["p", "Two"]], + ["li", ["p", "Three"]]], + ["p", "Multiple paragraphs:"], + ["ol", ["li", ["p", "Item 1, graf one."], + ["p", "Item 2. graf two. The quick brown fox jumped over the lazy dog's\u000aback."]], + ["li", ["p", "Item 2."]], + ["li", ["p", "Item 3."]]], "\u000a\u000a", ["h2", "Nested"], "\u000a\u000a", ["ul", ["li", "Tab\u000a", ["ul", ["li", "Tab\u000a", ["ul", ["li", "Tab"]]]]]], + ["p", "Here's another:"], + ["ol", ["li", "First"], + ["li", "Second:\u000a", ["ul", ["li", "Fee"], + ["li", "Fie"], + ["li", "Foe"]]], + ["li", "Third"]], + ["p", "Same thing but with paragraphs:"], + ["ol", ["li", ["p", "First"]], + ["li", ["p", "Second:"], + ["ul", ["li", "Fee"], + ["li", "Fie"], + ["li", "Foe"]]], + ["li", ["p", "Third"]]], + ["p", "This was an error in Markdown 1.0.1:"], + ["ul", ["li", ["p", "this"], + ["ul", ["li", "sub"]], + ["p", "that"]]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Ordered_and_unordered_lists.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Ordered_and_unordered_lists.text new file mode 100644 index 00000000..7f3b4977 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Ordered_and_unordered_lists.text @@ -0,0 +1,131 @@ +## Unordered + +Asterisks tight: + +* asterisk 1 +* asterisk 2 +* asterisk 3 + + +Asterisks loose: + +* asterisk 1 + +* asterisk 2 + +* asterisk 3 + +* * * + +Pluses tight: + ++ Plus 1 ++ Plus 2 ++ Plus 3 + + +Pluses loose: + ++ Plus 1 + ++ Plus 2 + ++ Plus 3 + +* * * + + +Minuses tight: + +- Minus 1 +- Minus 2 +- Minus 3 + + +Minuses loose: + +- Minus 1 + +- Minus 2 + +- Minus 3 + + +## Ordered + +Tight: + +1. First +2. Second +3. Third + +and: + +1. One +2. Two +3. Three + + +Loose using tabs: + +1. First + +2. Second + +3. Third + +and using spaces: + +1. One + +2. Two + +3. Three + +Multiple paragraphs: + +1. Item 1, graf one. + + Item 2. graf two. The quick brown fox jumped over the lazy dog's + back. + +2. Item 2. + +3. Item 3. + + + +## Nested + +* Tab + * Tab + * Tab + +Here's another: + +1. First +2. Second: + * Fee + * Fie + * Foe +3. Third + +Same thing but with paragraphs: + +1. First + +2. Second: + * Fee + * Fie + * Foe + +3. Third + + +This was an error in Markdown 1.0.1: + +* this + + * sub + + that diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Ordered_and_unordered_lists.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Ordered_and_unordered_lists.xhtml new file mode 100644 index 00000000..ba71eab3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Ordered_and_unordered_lists.xhtml @@ -0,0 +1,148 @@ +

    Unordered

    + +

    Asterisks tight:

    + +
      +
    • asterisk 1
    • +
    • asterisk 2
    • +
    • asterisk 3
    • +
    + +

    Asterisks loose:

    + +
      +
    • asterisk 1

    • +
    • asterisk 2

    • +
    • asterisk 3

    • +
    + +
    + +

    Pluses tight:

    + +
      +
    • Plus 1
    • +
    • Plus 2
    • +
    • Plus 3
    • +
    + +

    Pluses loose:

    + +
      +
    • Plus 1

    • +
    • Plus 2

    • +
    • Plus 3

    • +
    + +
    + +

    Minuses tight:

    + +
      +
    • Minus 1
    • +
    • Minus 2
    • +
    • Minus 3
    • +
    + +

    Minuses loose:

    + +
      +
    • Minus 1

    • +
    • Minus 2

    • +
    • Minus 3

    • +
    + +

    Ordered

    + +

    Tight:

    + +
      +
    1. First
    2. +
    3. Second
    4. +
    5. Third
    6. +
    + +

    and:

    + +
      +
    1. One
    2. +
    3. Two
    4. +
    5. Three
    6. +
    + +

    Loose using tabs:

    + +
      +
    1. First

    2. +
    3. Second

    4. +
    5. Third

    6. +
    + +

    and using spaces:

    + +
      +
    1. One

    2. +
    3. Two

    4. +
    5. Three

    6. +
    + +

    Multiple paragraphs:

    + +
      +
    1. Item 1, graf one.

      + +

      Item 2. graf two. The quick brown fox jumped over the lazy dog's +back.

    2. +
    3. Item 2.

    4. +
    5. Item 3.

    6. +
    + +

    Nested

    + +
      +
    • Tab +
        +
      • Tab +
          +
        • Tab
        • +
      • +
    • +
    + +

    Here's another:

    + +
      +
    1. First
    2. +
    3. Second: +
        +
      • Fee
      • +
      • Fie
      • +
      • Foe
      • +
    4. +
    5. Third
    6. +
    + +

    Same thing but with paragraphs:

    + +
      +
    1. First

    2. +
    3. Second:

      + +
        +
      • Fee
      • +
      • Fie
      • +
      • Foe
      • +
    4. +
    5. Third

    6. +
    + + +

    This was an error in Markdown 1.0.1:

    + +
      +
    • this

      + +
      • sub
      + +

      that

    • +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Strong_and_em_together.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Strong_and_em_together.json new file mode 100644 index 00000000..f0e9b359 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Strong_and_em_together.json @@ -0,0 +1,4 @@ +["html", ["p", ["strong", ["em", "This is strong and em."]]], + ["p", "So is ", ["strong", ["em", "this"]], " word."], + ["p", ["strong", ["em", "This is strong and em."]]], + ["p", "So is ", ["strong", ["em", "this"]], " word."]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Strong_and_em_together.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Strong_and_em_together.text new file mode 100644 index 00000000..95ee690d --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Strong_and_em_together.text @@ -0,0 +1,7 @@ +***This is strong and em.*** + +So is ***this*** word. + +___This is strong and em.___ + +So is ___this___ word. diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Strong_and_em_together.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Strong_and_em_together.xhtml new file mode 100644 index 00000000..71ec78c7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Strong_and_em_together.xhtml @@ -0,0 +1,7 @@ +

    This is strong and em.

    + +

    So is this word.

    + +

    This is strong and em.

    + +

    So is this word.

    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tabs.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tabs.json new file mode 100644 index 00000000..755f65b6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tabs.json @@ -0,0 +1,8 @@ +["html", ["ul", ["li", ["p", "this is a list item\u000aindented with tabs"]], + ["li", ["p", "this is a list item\u000aindented with spaces"]]], + ["p", "Code:"], + ["pre", ["code", "this code block is indented by one tab\u000a"]], + ["p", "And:"], + ["pre", ["code", " this code block is indented by two tabs\u000a"]], + ["p", "And:"], + ["pre", ["code", "+ this is an example list item\u000a indented with tabs\u000a\u000a+ this is an example list item\u000a indented with spaces\u000a"]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tabs.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tabs.text new file mode 100644 index 00000000..589d1136 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tabs.text @@ -0,0 +1,21 @@ ++ this is a list item + indented with tabs + ++ this is a list item + indented with spaces + +Code: + + this code block is indented by one tab + +And: + + this code block is indented by two tabs + +And: + + + this is an example list item + indented with tabs + + + this is an example list item + indented with spaces diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tabs.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tabs.xhtml new file mode 100644 index 00000000..3301ba80 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tabs.xhtml @@ -0,0 +1,25 @@ +
      +
    • this is a list item +indented with tabs

    • +
    • this is a list item +indented with spaces

    • +
    + +

    Code:

    + +
    this code block is indented by one tab
    +
    + +

    And:

    + +
        this code block is indented by two tabs
    +
    + +

    And:

    + +
    +   this is an example list item
    +    indented with tabs
    +
    ++   this is an example list item
    +    indented with spaces
    +
    diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tidyness.json b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tidyness.json new file mode 100644 index 00000000..38f3840e --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tidyness.json @@ -0,0 +1,4 @@ +["html", ["blockquote", ["p", "A list within a blockquote:"], + ["ul", ["li", "asterisk 1"], + ["li", "asterisk 2"], + ["li", "asterisk 3"]]]] diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tidyness.text b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tidyness.text new file mode 100644 index 00000000..5f18b8da --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tidyness.text @@ -0,0 +1,5 @@ +> A list within a blockquote: +> +> * asterisk 1 +> * asterisk 2 +> * asterisk 3 diff --git a/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tidyness.xhtml b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tidyness.xhtml new file mode 100644 index 00000000..f2a8ce70 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Markdown-from-MDTest1.1.mdtest/Tidyness.xhtml @@ -0,0 +1,8 @@ +
    +

    A list within a blockquote:

    +
      +
    • asterisk 1
    • +
    • asterisk 2
    • +
    • asterisk 3
    • +
    +
    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Backslash_escapes.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Backslash_escapes.json new file mode 100644 index 00000000..fe607646 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Backslash_escapes.json @@ -0,0 +1,5 @@ +["html", ["p", "Tricky combinaisons:"], + ["p", "backslash with \\-- two dashes"], + ["p", "backslash with \\> greater than"], + ["p", "\\[test](not a link)"], + ["p", "\\*no emphasis*"]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Backslash_escapes.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Backslash_escapes.text new file mode 100644 index 00000000..a5e769b7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Backslash_escapes.text @@ -0,0 +1 @@ +Tricky combinaisons: backslash with \\-- two dashes backslash with \\> greater than \\\[test](not a link) \\\*no emphasis* \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Backslash_escapes.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Backslash_escapes.xhtml new file mode 100644 index 00000000..08fb8ef8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Backslash_escapes.xhtml @@ -0,0 +1 @@ +

    Tricky combinaisons:

    backslash with \-- two dashes

    backslash with \> greater than

    \[test](not a link)

    \*no emphasis*

    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_Spans.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_Spans.json new file mode 100644 index 00000000..0854d4ff --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_Spans.json @@ -0,0 +1,2 @@ +["html", ["p", "From ", ["code", ""], "\u000aon two lines."], + ["p", "From ", ["code", ""], "\u000aon three lines."]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_Spans.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_Spans.text new file mode 100644 index 00000000..43f2bcfd --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_Spans.text @@ -0,0 +1,6 @@ +From `` +on two lines. + +From `` +on three lines. diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_Spans.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_Spans.xhtml new file mode 100644 index 00000000..9ed0df87 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_Spans.xhtml @@ -0,0 +1,6 @@ +

    From <!-- to --> +on two lines.

    + +

    From <!-- +to --> +on three lines.

    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_block_in_a_list_item.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_block_in_a_list_item.json new file mode 100644 index 00000000..aa10afbd --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_block_in_a_list_item.json @@ -0,0 +1,3 @@ +["html", ["ul", ["li", ["p", "List Item:"], + ["pre", ["code", "code block\u000a\u000awith a blank line\u000a"]], + ["p", "within a list item."]]]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_block_in_a_list_item.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_block_in_a_list_item.text new file mode 100644 index 00000000..3fa24c31 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_block_in_a_list_item.text @@ -0,0 +1,8 @@ + +* List Item: + + code block + + with a blank line + + within a list item. \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_block_in_a_list_item.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_block_in_a_list_item.xhtml new file mode 100644 index 00000000..7d57b1e7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Code_block_in_a_list_item.xhtml @@ -0,0 +1,10 @@ +
      +
    • List Item:

      + +
      code block
      +
      +with a blank line
      +
      + +

      within a list item.

    • +
    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Email_auto_links.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Email_auto_links.json new file mode 100644 index 00000000..935fb6d9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Email_auto_links.json @@ -0,0 +1,8 @@ +["html", ["p", ["a", { + "href": "mailto:michel.fortin@michelf.com" +}, +"michel.fortin@michelf.com"]], + ["p", "International domain names: ", ["a", { + "href": "mailto:help@tūdaliņ.lv" + }, + "help@tūdaliņ.lv"]]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Email_auto_links.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Email_auto_links.text new file mode 100644 index 00000000..a8af4ec3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Email_auto_links.text @@ -0,0 +1,3 @@ + + +International domain names: \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Email_auto_links.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Email_auto_links.xhtml new file mode 100644 index 00000000..a32c4087 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Email_auto_links.xhtml @@ -0,0 +1,3 @@ +

    michel.fortin@michelf.com

    + +

    International domain names: help@tūdaliņ.lv

    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Emphasis.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Emphasis.json new file mode 100644 index 00000000..bc25ffd9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Emphasis.json @@ -0,0 +1,47 @@ +["html", ["p", "Combined emphasis:"], + ["ol", ["li", ["strong", ["em", "test test"]]], + ["li", ["strong", ["em", "test test"]]], + ["li", ["em", "test ", ["strong", "test"]]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["em", ["strong", "test"], " test"]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["em", "test ", ["strong", "test"]]], + ["li", ["em", "test ", ["strong", "test"]]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["em", ["strong", "test"], " test"]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["em", "test ", ["strong", "test"]]]], + ["p", "Incorrect nesting:"], + ["ol", ["li", "*test ", ["strong", "test* test"]], + ["li", "_test ", ["strong", "test_ test"]], + ["li", "**test ", ["em", "test"], "* test*"], + ["li", "__test ", ["em", "test"], "_ test_"], + ["li", ["em", "test *test"], " test*"], + ["li", ["em", "test _test"], " test_"], + ["li", ["strong", "test ", ["strong", "test"], " test"]], + ["li", ["strong", "test ", ["strong", "test"], " test"]]], + ["p", "No emphasis:"], + ["ol", ["li", "test* test *test"], + ["li", "test** test **test"], + ["li", "test_ test _test"], + ["li", "test__ test __test"]], + ["p", "Middle-word emphasis (asterisks):"], + ["ol", ["li", ["em", "a"], "b"], + ["li", "a", ["em", "b"]], + ["li", "a", ["em", "b"], "c"], + ["li", ["strong", "a"], "b"], + ["li", "a", ["strong", "b"]], + ["li", "a", ["strong", "b"], "c"]], + ["p", "Middle-word emphasis (underscore):"], + ["ol", ["li", ["em", "a"], "b"], + ["li", "a", ["em", "b"]], + ["li", "a", ["em", "b"], "c"], + ["li", ["strong", "a"], "b"], + ["li", "a", ["strong", "b"]], + ["li", "a", ["strong", "b"], "c"]], + ["p", "my", ["em", "precious"], "file.txt"], "\u000a\u000a", ["h2", "Tricky Cases"], "\u000a\u000a", ["p", "E**. ", ["strong", "Test"], " TestTestTest"], + ["p", "E**. ", ["strong", "Test"], " Test Test Test"]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Emphasis.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Emphasis.text new file mode 100644 index 00000000..ec48dec0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Emphasis.text @@ -0,0 +1,69 @@ +Combined emphasis: + +1. ***test test*** +2. ___test test___ +3. *test **test*** +4. **test *test*** +5. ***test* test** +6. ***test** test* +7. ***test* test** +8. **test *test*** +9. *test **test*** +10. _test __test___ +11. __test _test___ +12. ___test_ test__ +13. ___test__ test_ +14. ___test_ test__ +15. __test _test___ +16. _test __test___ + + +Incorrect nesting: + +1. *test **test* test** +2. _test __test_ test__ +3. **test *test** test* +4. __test _test__ test_ +5. *test *test* test* +6. _test _test_ test_ +7. **test **test** test** +8. __test __test__ test__ + + + +No emphasis: + +1. test* test *test +2. test** test **test +3. test_ test _test +4. test__ test __test + + + +Middle-word emphasis (asterisks): + +1. *a*b +2. a*b* +3. a*b*c +4. **a**b +5. a**b** +6. a**b**c + + +Middle-word emphasis (underscore): + +1. _a_b +2. a_b_ +3. a_b_c +4. __a__b +5. a__b__ +6. a__b__c + +my_precious_file.txt + + +## Tricky Cases + +E**. **Test** TestTestTest + +E**. **Test** Test Test Test diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Emphasis.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Emphasis.xhtml new file mode 100644 index 00000000..73991324 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Emphasis.xhtml @@ -0,0 +1,72 @@ +

    Combined emphasis:

    + +
      +
    1. test test
    2. +
    3. test test
    4. +
    5. test test
    6. +
    7. test test
    8. +
    9. test test
    10. +
    11. test test
    12. +
    13. test test
    14. +
    15. test test
    16. +
    17. test test
    18. +
    19. test test
    20. +
    21. test test
    22. +
    23. test test
    24. +
    25. test test
    26. +
    27. test test
    28. +
    29. test test
    30. +
    31. test test
    32. +
    + +

    Incorrect nesting:

    + +
      +
    1. *test test* test
    2. +
    3. _test test_ test
    4. +
    5. **test test* test*
    6. +
    7. __test test_ test_
    8. +
    9. test *test test*
    10. +
    11. test _test test_
    12. +
    13. test test test
    14. +
    15. test test test
    16. +
    + +

    No emphasis:

    + +
      +
    1. test* test *test
    2. +
    3. test** test **test
    4. +
    5. test_ test _test
    6. +
    7. test__ test __test
    8. +
    + +

    Middle-word emphasis (asterisks):

    + +
      +
    1. ab
    2. +
    3. ab
    4. +
    5. abc
    6. +
    7. ab
    8. +
    9. ab
    10. +
    11. abc
    12. +
    + +

    Middle-word emphasis (underscore):

    + +
      +
    1. ab
    2. +
    3. ab
    4. +
    5. abc
    6. +
    7. ab
    8. +
    9. ab
    10. +
    11. abc
    12. +
    + +

    mypreciousfile.txt

    + +

    Tricky Cases

    + +

    E**. Test TestTestTest

    + +

    E**. Test Test Test Test

    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Headers.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Headers.json new file mode 100644 index 00000000..bd094895 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Headers.json @@ -0,0 +1,3 @@ +["html", ["h1", "Header"], "\u000a\u000a", ["h2", "Header"], "\u000a\u000a", ["h3", "Header"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["h1", "Header"], "\u000a\u000a", ["p", "Paragraph"], "\u000a\u000a", ["h2", "Header"], "\u000a\u000a", ["p", "Paragraph"], "\u000a\u000a", ["h3", "Header"], "\u000a\u000a", ["p", "Paragraph"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", "Paragraph"], "\u000a\u000a", ["h1", "Header"], "\u000a\u000a", ["p", "Paragraph"], + ["p", "Paragraph"], "\u000a\u000a", ["h2", "Header"], "\u000a\u000a", ["p", "Paragraph"], + ["p", "Paragraph"], "\u000a\u000a", ["h3", "Header"], "\u000a\u000a", ["p", "Paragraph"]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Headers.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Headers.text new file mode 100644 index 00000000..3a39174a --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Headers.text @@ -0,0 +1,9 @@ +Header ====== Header ------ ### Header + + - - - + +Header ====== Paragraph Header ------ Paragraph ### Header Paragraph + + - - - + +Paragraph Header ====== Paragraph Paragraph Header ------ Paragraph Paragraph ### Header Paragraph \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Headers.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Headers.xhtml new file mode 100644 index 00000000..3adb4707 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Headers.xhtml @@ -0,0 +1,39 @@ +

    Header

    + +

    Header

    + +

    Header

    + +
    + +

    Header

    + +

    Paragraph

    + +

    Header

    + +

    Paragraph

    + +

    Header

    + +

    Paragraph

    + +
    + +

    Paragraph

    + +

    Header

    + +

    Paragraph

    + +

    Paragraph

    + +

    Header

    + +

    Paragraph

    + +

    Paragraph

    + +

    Header

    + +

    Paragraph

    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Horizontal_Rules.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Horizontal_Rules.json new file mode 100644 index 00000000..35f9138f --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Horizontal_Rules.json @@ -0,0 +1,9 @@ +["html", ["p", "Horizontal rules:"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", "Not horizontal rules (testing for a bug in 1.0.1j):"], + ["p", "+++"], + ["p", ",,,"], + ["p", "==="], + ["p", "???"], + ["p", "AAA"], + ["p", "jjj"], + ["p", "j j j"], + ["p", "n n n"]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Horizontal_Rules.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Horizontal_Rules.text new file mode 100644 index 00000000..8e2da0b1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Horizontal_Rules.text @@ -0,0 +1,29 @@ +Horizontal rules: + +- - - + +* * * + +*** + +--- + +___ + +Not horizontal rules (testing for a bug in 1.0.1j): + ++++ + +,,, + +=== + +??? + +AAA + +jjj + +j j j + +n n n diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Horizontal_Rules.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Horizontal_Rules.xhtml new file mode 100644 index 00000000..b9170b1e --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Horizontal_Rules.xhtml @@ -0,0 +1,30 @@ +

    Horizontal rules:

    + +
    + +
    + +
    + +
    + +
    + +

    Not horizontal rules (testing for a bug in 1.0.1j):

    + +

    +++

    + +

    ,,,

    + +

    ===

    + +

    ???

    + +

    AAA

    + +

    jjj

    + +

    j j j

    + +

    n n n

    + diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).html b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).html new file mode 100644 index 00000000..facfefba --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).html @@ -0,0 +1,15 @@ +

    With some attributes:

    + +
    + foo +
    + +
    + foo +
    + +

    Hr's:

    + +
    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).json new file mode 100644 index 00000000..0cdbfd67 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).json @@ -0,0 +1,11 @@ +["html", ["p", "With some attributes:"], "\u000a\u000a", ["div", { + "id": "test" +}, +"\u000a foo\u000a"], "\u000a\u000a", ["div", { + "id": "test", + "class": "nono" +}, +"\u000a foo\u000a"], "\u000a\u000a", ["p", "Hr's:"], "\u000a\u000a", ["hr", { + "class": "foo", + "id": "bar" +}]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).text new file mode 100644 index 00000000..9177105e --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Simple).text @@ -0,0 +1,15 @@ +With some attributes: + +
    + foo +
    + +
    + foo +
    + +Hr's: + +
    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Span).json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Span).json new file mode 100644 index 00000000..77e2b96c --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Span).json @@ -0,0 +1,11 @@ +["html", ["p", ["abbr", { + "title": "` **Attribute Content Is Not A Code Span** `" +}, +"ACINACS"]], + ["p", ["abbr", { + "title": "`first backtick!" + }, + "SB"], " \u000a", ["abbr", { + "title": "`second backtick!" + }, + "SB"]]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Span).text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Span).text new file mode 100644 index 00000000..19028bb3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Span).text @@ -0,0 +1,4 @@ +ACINACS + +SB +SB \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Span).xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Span).xhtml new file mode 100644 index 00000000..4d18affe --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_(Span).xhtml @@ -0,0 +1,4 @@ +

    ACINACS

    + +

    SB +SB

    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.html b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.html new file mode 100644 index 00000000..b45f0148 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.html @@ -0,0 +1,9 @@ +

    Paragraph one.

    + + + +

    Paragraph two.

    + + + +

    The end.

    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.json new file mode 100644 index 00000000..fd65c352 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.json @@ -0,0 +1 @@ +["html", ["p", "Paragraph one."], "\u000a\u000a", "\u000a\u000a", ["p", "Paragraph two."], "\u000a\u000a", "\u000a\u000a", ["p", "The end."]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.text new file mode 100644 index 00000000..d57d00aa --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Inline_HTML_comments.text @@ -0,0 +1,9 @@ +Paragraph one. + + + +Paragraph two. + + + +The end. diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Ins_and_del.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Ins_and_del.json new file mode 100644 index 00000000..f907dab1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Ins_and_del.json @@ -0,0 +1,3 @@ +["html", ["p", "Here is a block tag ins:"], "\u000a\u000a", ["ins", ["p", "Some text"]], "\u000a\u000a", ["p", ["ins", "And here it is inside a paragraph."]], + ["p", "And here it is ", ["ins", "in the middle of"], " a paragraph."], "\u000a\u000a", ["del", ["p", "Some text"]], "\u000a\u000a", ["p", ["del", "And here is ins as a paragraph."]], + ["p", "And here it is ", ["del", "in the middle of"], " a paragraph."]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Ins_and_del.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Ins_and_del.text new file mode 100644 index 00000000..2d54c660 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Ins_and_del.text @@ -0,0 +1,17 @@ +Here is a block tag ins: + + +

    Some text

    +
    + +And here it is inside a paragraph. + +And here it is in the middle of a paragraph. + + +

    Some text

    +
    + +And here is ins as a paragraph. + +And here it is in the middle of a paragraph. diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Ins_and_del.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Ins_and_del.xhtml new file mode 100644 index 00000000..60e8c5ff --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Ins_and_del.xhtml @@ -0,0 +1,17 @@ +

    Here is a block tag ins:

    + + +

    Some text

    +
    + +

    And here it is inside a paragraph.

    + +

    And here it is in the middle of a paragraph.

    + + +

    Some text

    +
    + +

    And here is ins as a paragraph.

    + +

    And here it is in the middle of a paragraph.

    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Links_inline_style.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Links_inline_style.json new file mode 100644 index 00000000..f7faf552 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Links_inline_style.json @@ -0,0 +1,4 @@ +["html", ["p", ["a", { + "href": "?}]*+|&)" +}, +"silly URL w/ angle brackets"], "."]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Links_inline_style.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Links_inline_style.text new file mode 100644 index 00000000..600a0442 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Links_inline_style.text @@ -0,0 +1 @@ +[silly URL w/ angle brackets](). diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Links_inline_style.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Links_inline_style.xhtml new file mode 100644 index 00000000..d3e4d111 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Links_inline_style.xhtml @@ -0,0 +1 @@ +

    silly URL w/ angle brackets.

    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/MD5_Hashes.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/MD5_Hashes.json new file mode 100644 index 00000000..17294783 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/MD5_Hashes.json @@ -0,0 +1,3 @@ +["html", ["h1", "Character Escapes"], "\u000a\u000a", ["p", "The MD5 value for ", ["code", "+"], " is \"26b17225b626fb9238849fd60eabdf60\"."], "\u000a\u000a", ["h1", "HTML Blocks"], "\u000a\u000a", ["p", "test"], + ["p", "The MD5 value for ", ["code", "

    test

    "], " is:"], + ["p", "6205333b793f34273d75379350b36826"]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/MD5_Hashes.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/MD5_Hashes.text new file mode 100644 index 00000000..7e032218 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/MD5_Hashes.text @@ -0,0 +1,11 @@ +# Character Escapes + +The MD5 value for `+` is "26b17225b626fb9238849fd60eabdf60". + +# HTML Blocks + +

    test

    + +The MD5 value for `

    test

    ` is: + +6205333b793f34273d75379350b36826 \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/MD5_Hashes.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/MD5_Hashes.xhtml new file mode 100644 index 00000000..894e4aa7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/MD5_Hashes.xhtml @@ -0,0 +1,11 @@ +

    Character Escapes

    + +

    The MD5 value for + is "26b17225b626fb9238849fd60eabdf60".

    + +

    HTML Blocks

    + +

    test

    + +

    The MD5 value for <p>test</p> is:

    + +

    6205333b793f34273d75379350b36826

    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Nesting.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Nesting.json new file mode 100644 index 00000000..7aab7f0e --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Nesting.json @@ -0,0 +1,18 @@ +["html", ["p", "Valid nesting:"], + ["p", ["strong", ["a", { + "href": "url" + }, + "Link"]]], + ["p", ["a", { + "href": "url" + }, + ["strong", "Link"]]], + ["p", ["strong", ["a", { + "href": "url" + }, + ["strong", "Link"]]]], + ["p", "Invalid nesting:"], + ["p", ["a", { + "href": "url" + }, + "[Link](url)"]]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Nesting.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Nesting.text new file mode 100644 index 00000000..791538c0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Nesting.text @@ -0,0 +1,11 @@ +Valid nesting: + +**[Link](url)** + +[**Link**](url) + +**[**Link**](url)** + +Invalid nesting: + +[[Link](url)](url) \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Nesting.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Nesting.xhtml new file mode 100644 index 00000000..37845d31 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Nesting.xhtml @@ -0,0 +1,11 @@ +

    Valid nesting:

    + +

    Link

    + +

    Link

    + +

    Link

    + +

    Invalid nesting:

    + +

    [Link](url)

    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/PHP-Specific_Bugs.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/PHP-Specific_Bugs.json new file mode 100644 index 00000000..ce3dfae4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/PHP-Specific_Bugs.json @@ -0,0 +1,3 @@ +["html", ["p", "This tests for a bug where quotes escaped by PHP when using \u000a", ["code", "preg_replace"], " with the ", ["code", "/e"], " modifier must be correctly unescaped\u000a(hence the ", ["code", "_UnslashQuotes"], " function found only in PHP Markdown)."], + ["p", "Headers below should appear exactly as they are typed (no backslash\u000aadded or removed)."], "\u000a\u000a", ["h1", "Header \"quoted\\\" again \\\"\""], "\u000a\u000a", ["h2", "Header \"quoted\\\" again \\\"\""], "\u000a\u000a", ["h3", "Header \"quoted\\\" again \\\"\""], "\u000a\u000a", ["p", "Test with tabs for ", ["code", "_Detab"], ":"], + ["pre", ["code", "Code 'block' with some \"tabs\" and \"quotes\"\u000a"]]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/PHP-Specific_Bugs.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/PHP-Specific_Bugs.text new file mode 100644 index 00000000..246b60d1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/PHP-Specific_Bugs.text @@ -0,0 +1,22 @@ +This tests for a bug where quotes escaped by PHP when using +`preg_replace` with the `/e` modifier must be correctly unescaped +(hence the `_UnslashQuotes` function found only in PHP Markdown). + + + +Headers below should appear exactly as they are typed (no backslash +added or removed). + +Header "quoted\" again \\"" +=========================== + +Header "quoted\" again \\"" +--------------------------- + +### Header "quoted\" again \\"" ### + + + +Test with tabs for `_Detab`: + + Code 'block' with some "tabs" and "quotes" diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/PHP-Specific_Bugs.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/PHP-Specific_Bugs.xhtml new file mode 100644 index 00000000..c982417b --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/PHP-Specific_Bugs.xhtml @@ -0,0 +1,17 @@ +

    This tests for a bug where quotes escaped by PHP when using +preg_replace with the /e modifier must be correctly unescaped +(hence the _UnslashQuotes function found only in PHP Markdown).

    + +

    Headers below should appear exactly as they are typed (no backslash +added or removed).

    + +

    Header "quoted\" again \""

    + +

    Header "quoted\" again \""

    + +

    Header "quoted\" again \""

    + +

    Test with tabs for _Detab:

    + +
    Code    'block' with    some    "tabs"  and "quotes"
    +
    diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Parens_in_URL.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Parens_in_URL.json new file mode 100644 index 00000000..207a072f --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Parens_in_URL.json @@ -0,0 +1,30 @@ +["html", ["p", ["a", { + "href": "/url(test)", + "title": "title" +}, +"Inline link 1 with parens"], "."], + ["p", ["a", { + "href": "/url(test)", + "title": "title" + }, + "Inline link 2 with parens"], "."], + ["p", ["a", { + "href": "/url(test)", + "title": "title" + }, + "Inline link 3 with non-escaped parens"], "."], + ["p", ["a", { + "href": "/url(test)", + "title": "title" + }, + "Inline link 4 with non-escaped parens"], "."], + ["p", ["a", { + "href": "/url(test)", + "title": "title" + }, + "Reference link 1 with parens"], "."], + ["p", ["a", { + "href": "/url(test)", + "title": "title" + }, + "Reference link 2 with parens"], "."]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Parens_in_URL.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Parens_in_URL.text new file mode 100644 index 00000000..bb7be4fb --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Parens_in_URL.text @@ -0,0 +1,14 @@ +[Inline link 1 with parens](/url\(test\) "title"). + +[Inline link 2 with parens]( "title"). + +[Inline link 3 with non-escaped parens](/url(test) "title"). + +[Inline link 4 with non-escaped parens]( "title"). + +[Reference link 1 with parens][1]. + +[Reference link 2 with parens][2]. + + [1]: /url(test) "title" + [2]: "title" diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Parens_in_URL.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Parens_in_URL.xhtml new file mode 100644 index 00000000..a81aa029 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Parens_in_URL.xhtml @@ -0,0 +1,11 @@ +

    Inline link 1 with parens.

    + +

    Inline link 2 with parens.

    + +

    Inline link 3 with non-escaped parens.

    + +

    Inline link 4 with non-escaped parens.

    + +

    Reference link 1 with parens.

    + +

    Reference link 2 with parens.

    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Tight_blocks.json b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Tight_blocks.json new file mode 100644 index 00000000..116b198b --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Tight_blocks.json @@ -0,0 +1,6 @@ +["html", ["p", "Paragraph and no space:\u000a* ciao"], + ["p", "Paragraph and 1 space:\u000a * ciao"], + ["p", "Paragraph and 3 spaces:\u000a * ciao"], + ["p", "Paragraph and 4 spaces:\u000a * ciao"], + ["p", "Paragraph before header:"], "\u000a\u000a", ["h1", "Header"], "\u000a\u000a", ["p", "Paragraph before blockquote:"], + ["blockquote", ["p", "Some quote."]]] diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Tight_blocks.text b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Tight_blocks.text new file mode 100644 index 00000000..ae4cdcb4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Tight_blocks.text @@ -0,0 +1 @@ +Paragraph and no space: * ciao Paragraph and 1 space: * ciao Paragraph and 3 spaces: * ciao Paragraph and 4 spaces: * ciao Paragraph before header: #Header Paragraph before blockquote: >Some quote. \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Tight_blocks.xhtml b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Tight_blocks.xhtml new file mode 100644 index 00000000..86554308 --- /dev/null +++ b/node_modules/markdown/test/fixtures/PHP_Markdown-from-MDTest1.1.mdtest/Tight_blocks.xhtml @@ -0,0 +1,21 @@ +

    Paragraph and no space: +* ciao

    + +

    Paragraph and 1 space: + * ciao

    + +

    Paragraph and 3 spaces: + * ciao

    + +

    Paragraph and 4 spaces: + * ciao

    + +

    Paragraph before header:

    + +

    Header

    + +

    Paragraph before blockquote:

    + +
    +

    Some quote.

    +
    diff --git a/node_modules/markdown/test/fixtures/README b/node_modules/markdown/test/fixtures/README new file mode 100644 index 00000000..6d3176fa --- /dev/null +++ b/node_modules/markdown/test/fixtures/README @@ -0,0 +1,42 @@ +All of these tests (so far) were copied from: + + github.com/bobtfish/text-markdown/t @ 29ffc3 + +which is licensed as follows: + +Copyright (c) 2004, John Gruber + +All rights reserved. + +MultiMarkdown changes Copyright (c) 2005-2006 Fletcher T. Penney + All rights reserved. + +Text::MultiMarkdown changes Copyright (c) 2006-2009 Darren Kulp + and Tomas Doran + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name "Markdown" nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +This software is provided by the copyright holders and contributors "as +is" and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. In no event shall the copyright owner +or contributors be liable for any direct, indirect, incidental, special, +exemplary, or consequential damages (including, but not limited to, +procurement of substitute goods or services; loss of use, data, or +profits; or business interruption) however caused and on any theory of +liability, whether in contract, strict liability, or tort (including +negligence or otherwise) arising in any way out of the use of this +software, even if advised of the possibility of such damage. diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/CoreDumps5.8.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/CoreDumps5.8.json new file mode 100644 index 00000000..899061f4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/CoreDumps5.8.json @@ -0,0 +1,3 @@ +["html", ["ul", ["li", "Unordered\u000a", ["ol", ["li", "Ordered"]]]], + ["p", "Text"], + ["ul", ["li", "Unordered\u000a", ["ol", ["li", "Ordered"]]]]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/CoreDumps5.8.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/CoreDumps5.8.text new file mode 100644 index 00000000..30ce3125 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/CoreDumps5.8.text @@ -0,0 +1,7 @@ +* Unordered +1. Ordered + +Text + +* Unordered +1. Ordered diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/CoreDumps5.8.xhtml b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/CoreDumps5.8.xhtml new file mode 100644 index 00000000..8a2963e5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/CoreDumps5.8.xhtml @@ -0,0 +1,15 @@ +
      +
    • Unordered +
        +
      1. Ordered
      2. +
    • +
    + +

    Text

    + +
      +
    • Unordered +
        +
      1. Ordered
      2. +
    • +
    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Emphasis.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Emphasis.json new file mode 100644 index 00000000..f38d5747 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Emphasis.json @@ -0,0 +1,2 @@ +["html", ["p", ["em", "M*A*S*H"], " here I am going with original Markdown.."], + ["p", "foo_bar_bas I am going with PHP Markdown Extra here (by default, there is an option for original style behavior - see\u000adocs).."]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Emphasis.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Emphasis.text new file mode 100644 index 00000000..104f90e4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Emphasis.text @@ -0,0 +1,4 @@ +_M*A*S*H_ here I am going with original Markdown.. + +foo_bar_bas I am going with PHP Markdown Extra here (by default, there is an option for original style behavior - see +docs).. diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Emphasis.xhtml b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Emphasis.xhtml new file mode 100644 index 00000000..96cef6d9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Emphasis.xhtml @@ -0,0 +1,4 @@ +

    M*A*S*H here I am going with original Markdown..

    + +

    foo_bar_bas I am going with PHP Markdown Extra here (by default, there is an option for original style behavior - see +docs)..

    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML-Comment-encoding.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML-Comment-encoding.json new file mode 100644 index 00000000..93946a00 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML-Comment-encoding.json @@ -0,0 +1,3 @@ +["html", ["p", "A markdown paragraph with a comment that ", ["em", "will"], " be processed by original Markdown. However MultiMarkdown and Pandoc do not convert the & sigil in the comment.. "], + ["p", "A paragraph "], + ["p"]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML-Comment-encoding.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML-Comment-encoding.text new file mode 100644 index 00000000..557c6afc --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML-Comment-encoding.text @@ -0,0 +1,5 @@ +A markdown paragraph with a comment that *will* be processed by original Markdown. However MultiMarkdown and Pandoc do not convert the & sigil in the comment.. + +A paragraph + +

    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML-Comment-encoding.xhtml b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML-Comment-encoding.xhtml new file mode 100644 index 00000000..b19577fd --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML-Comment-encoding.xhtml @@ -0,0 +1,5 @@ +

    A markdown paragraph with a comment that will be processed by original Markdown. However MultiMarkdown and Pandoc do not convert the & sigil in the comment..

    + +

    A paragraph

    + +

    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML5-attributes.html b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML5-attributes.html new file mode 100644 index 00000000..9dc2b471 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML5-attributes.html @@ -0,0 +1,11 @@ +

    foo

    + +

    +this is a paragraph +

    + +

    +an h2 +

    + +

    normal

    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML5-attributes.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML5-attributes.json new file mode 100644 index 00000000..1c5cf39f --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML5-attributes.json @@ -0,0 +1,10 @@ +["html", ["h1", { + "class": "foo" +}, +"foo"], "\u000a\u000a", ["p", { + "class": "bar" +}, +"\u000athis is a paragraph\u000a"], "\u000a\u000a", ["h2", { + "class": "bar" +}, +"\u000aan h2\u000a"], "\u000a\u000a", ["p", "normal"]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML5-attributes.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML5-attributes.text new file mode 100644 index 00000000..66d655ac --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/HTML5-attributes.text @@ -0,0 +1,11 @@ +

    foo

    + +

    +this is a paragraph +

    + +

    +an h2 +

    + +normal diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_brackets.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_brackets.json new file mode 100644 index 00000000..c4577b69 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_brackets.json @@ -0,0 +1,5 @@ +["html", ["p", ["a", { + "href": "http://en.wikipedia.org/wiki/ZIP_(file_format)", + "title": "ZIP (file format) - Wikipedia, the free encyclopedia" +}, +"ZIP archives"]]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_brackets.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_brackets.text new file mode 100644 index 00000000..6dd3c5d5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_brackets.text @@ -0,0 +1,2 @@ +[ZIP archives](http://en.wikipedia.org/wiki/ZIP_(file_format) "ZIP (file format) - Wikipedia, the free encyclopedia") + diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_brackets.xhtml b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_brackets.xhtml new file mode 100644 index 00000000..75376b98 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_brackets.xhtml @@ -0,0 +1 @@ +

    ZIP archives

    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_1.html b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_1.html new file mode 100644 index 00000000..386174a2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_1.html @@ -0,0 +1,4 @@ +

    http://bugs.debian.org/459885

    + +

    link +text

    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_1.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_1.json new file mode 100644 index 00000000..a793616b --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_1.json @@ -0,0 +1,8 @@ +["html", ["p", ["a", { + "href": "http://bugs.debian.org/459885" +}, +"http://bugs.debian.org/459885"]], + ["p", ["a", { + "href": "/someurl/" + }, + "link \u000atext"]]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_1.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_1.text new file mode 100644 index 00000000..9744d4f8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_1.text @@ -0,0 +1,7 @@ + + +[link +text] [link +id] + +[link id]: /someurl/ diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_2.html b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_2.html new file mode 100644 index 00000000..7be828bd --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_2.html @@ -0,0 +1,4 @@ +

    http://bugs.debian.org/459885

    + +

    Bla, bla, bla, bla, bla, bla, bla, bla, bla, bla bla. This is my
    +University
    .

    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_2.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_2.json new file mode 100644 index 00000000..6a43f3b1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_2.json @@ -0,0 +1,8 @@ +["html", ["p", ["a", { + "href": "http://bugs.debian.org/459885" +}, +"http://bugs.debian.org/459885"]], + ["p", "Bla, bla, bla, bla, bla, bla, bla, bla, bla, bla bla. This is ", ["a", { + "href": "http://www.ua.es" + }, + "my ", ["br"], "\u000aUniversity"], "."]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_2.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_2.text new file mode 100644 index 00000000..773679e6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_multiline_bugs_2.text @@ -0,0 +1,6 @@ + + +Bla, bla, bla, bla, bla, bla, bla, bla, bla, bla bla. This is [my +University][]. + + [my university]: http://www.ua.es diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_reference_style.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_reference_style.json new file mode 100644 index 00000000..ea65cafd --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_reference_style.json @@ -0,0 +1,88 @@ +["html", ["p", "Foo ", ["a", { + "href": "/url/", + "title": "Title" +}, +"bar"], "."], + ["p", "Foo ", ["a", { + "href": "/url/", + "title": "Title" + }, + "bar"], "."], + ["p", "Foo ", ["a", { + "href": "/url/", + "title": "Title" + }, + "bar"], "."], + ["p", "With ", ["a", { + "href": "/url/" + }, + "embedded [brackets]"], "."], + ["p", "Indented ", ["a", { + "href": "/url" + }, + "once"], "."], + ["p", "Indented ", ["a", { + "href": "/url" + }, + "twice"], "."], + ["p", "Indented ", ["a", { + "href": "/url" + }, + "thrice"], "."], + ["p", "Indented [four][] times."], + ["pre", ["code", "[four]: /url\u000a"]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", ["a", { + "href": "foo" +}, +"this"], " should work"], + ["p", "So should ", ["a", { + "href": "foo" + }, + "this"], "."], + ["p", "And ", ["a", { + "href": "foo" + }, + "this"], "."], + ["p", "And ", ["a", { + "href": "foo" + }, + "this"], "."], + ["p", "And ", ["a", { + "href": "foo" + }, + "this"], "."], + ["p", "But not [that] []."], + ["p", "Nor [that][]."], + ["p", "Nor [that]."], + ["p", "[Something in brackets like ", ["a", { + "href": "foo" + }, + "this"], " should work]"], + ["p", "[Same with ", ["a", { + "href": "foo" + }, + "this"], ".]"], + ["p", "In this case, ", ["a", { + "href": "/somethingelse/" + }, + "this"], " points to something else."], + ["p", "Backslashing should suppress [this] and [this]."], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", "Here's one where the ", ["a", { + "href": "/url/" +}, +"link\u000abreaks"], " across lines."], + ["p", "Here's another where the ", ["a", { + "href": "/url/" + }, + "link \u000abreaks"], " across lines, but with a line-ending space."], + ["p", "More multi line edge cases. First a broken link id"], + ["p", ["a", { + "href": "/someurl/" + }, + "link \u000atext"]], + ["p", "Then a line with 2 chars of trailing whitespace and a line break ", ["a", { + "href": "http://www.ua.es" + }, + "my ", ["br"], "\u000aUniversity"], "."], + ["p", "The a shortcut reference link with 2 chars of trailing whitespace and a line break ", ["a", { + "href": "http://www.ua.es" + }, + "my ", ["br"], "\u000aUniversity"], "."]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_reference_style.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_reference_style.text new file mode 100644 index 00000000..8b1aaf96 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_reference_style.text @@ -0,0 +1,87 @@ +Foo [bar] [1]. + +Foo [bar][1]. + +Foo [bar] +[1]. + +[1]: /url/ "Title" + + +With [embedded [brackets]] [b]. + + +Indented [once][]. + +Indented [twice][]. + +Indented [thrice][]. + +Indented [four][] times. + + [once]: /url + + [twice]: /url + + [thrice]: /url + + [four]: /url + + +[b]: /url/ + +* * * + +[this] [this] should work + +So should [this][this]. + +And [this] []. + +And [this][]. + +And [this]. + +But not [that] []. + +Nor [that][]. + +Nor [that]. + +[Something in brackets like [this][] should work] + +[Same with [this].] + +In this case, [this](/somethingelse/) points to something else. + +Backslashing should suppress \[this] and [this\]. + +[this]: foo + + +* * * + +Here's one where the [link +breaks] across lines. + +Here's another where the [link +breaks] across lines, but with a line-ending space. + + +[link breaks]: /url/ + +More multi line edge cases. First a broken link id + +[link +text] [link +id] + +[link id]: /someurl/ + +Then a line with 2 chars of trailing whitespace and a line break [my +University][]. + +The a shortcut reference link with 2 chars of trailing whitespace and a line break [my +University]. + + [my university]: http://www.ua.es \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_reference_style.xhtml b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_reference_style.xhtml new file mode 100644 index 00000000..07937219 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Links_reference_style.xhtml @@ -0,0 +1,63 @@ +

    Foo bar.

    + +

    Foo bar.

    + +

    Foo bar.

    + +

    With embedded [brackets].

    + +

    Indented once.

    + +

    Indented twice.

    + +

    Indented thrice.

    + +

    Indented [four][] times.

    + +
    [four]: /url
    +
    + +
    + +

    this should work

    + +

    So should this.

    + +

    And this.

    + +

    And this.

    + +

    And this.

    + +

    But not [that] [].

    + +

    Nor [that][].

    + +

    Nor [that].

    + +

    [Something in brackets like this should work]

    + +

    [Same with this.]

    + +

    In this case, this points to something else.

    + +

    Backslashing should suppress [this] and [this].

    + +
    + +

    Here's one where the link +breaks across lines.

    + +

    Here's another where the link +breaks across lines, but with a line-ending space.

    + +

    More multi line edge cases. First a broken link id

    + +

    link +text

    + +

    Then a line with 2 chars of trailing whitespace and a line break my
    +University
    .

    + +

    The a shortcut reference link with 2 chars of trailing whitespace and a line break my
    +University
    .

    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Lists-multilevel-md5-edgecase.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Lists-multilevel-md5-edgecase.json new file mode 100644 index 00000000..3c89c1b9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Lists-multilevel-md5-edgecase.json @@ -0,0 +1,8 @@ +["html", ["h1", "text1"], "\u000a\u000a", ["ul", ["li", ["p", "text2"], + ["ul", ["li", "text3"]], + ["p", "text4"]]], "\u000a\u000a", ["h2", "text5"], "\u000a\u000a", ["ul", ["li", ["p", "text6"], + ["ul", ["li", "text7"]], + ["p", "text8"]]], "\u000a\u000a", ["h2", "text9"], "\u000a\u000a", ["ul", ["li", ["p", "text10"], + ["ul", ["li", "text11"]], + ["p", "text12"], + ["p", "text13"]]]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Lists-multilevel-md5-edgecase.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Lists-multilevel-md5-edgecase.text new file mode 100644 index 00000000..6bd63e8d --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Lists-multilevel-md5-edgecase.text @@ -0,0 +1,25 @@ +# text1 + + * text2 + + * text3 + + text4 + +## text5 + + * text6 + + * text7 + + text8 + +## text9 + + * text10 + + * text11 + + text12 + + text13 diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Lists-multilevel-md5-edgecase.xhtml b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Lists-multilevel-md5-edgecase.xhtml new file mode 100644 index 00000000..9c7617c4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Lists-multilevel-md5-edgecase.xhtml @@ -0,0 +1,37 @@ +

    text1

    + +
      +
    • text2

      + +
        +
      • text3
      • +
      + +

      text4

    • +
    + +

    text5

    + +
      +
    • text6

      + +
        +
      • text7
      • +
      + +

      text8

    • +
    + +

    text9

    + +
      +
    • text10

      + +
        +
      • text11
      • +
      + +

      text12

      + +

      text13

    • +
    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/PHP-ASP_tags.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/PHP-ASP_tags.json new file mode 100644 index 00000000..347d3d96 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/PHP-ASP_tags.json @@ -0,0 +1,5 @@ +["html", ["p", "I am going with the same as Markdown.pl 1.0.2b8 here. ", ["em", "However"], " I reserve the right to also leave Template toolkit alone at a later date if I need to.."], "\u000a\u000a", ["foo", { + "ok": "ok", + "_": "_" +}, +"\u000a\u000a", "\u000a\u000a", ["p", "[% template_toolkit %]"]]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/PHP-ASP_tags.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/PHP-ASP_tags.text new file mode 100644 index 00000000..6cd1887c --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/PHP-ASP_tags.text @@ -0,0 +1,7 @@ +I am going with the same as Markdown.pl 1.0.2b8 here. *However* I reserve the right to also leave Template toolkit alone at a later date if I need to.. + +<%foo ok %> + + + +[% template_toolkit %] \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/PHP-ASP_tags.xhtml b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/PHP-ASP_tags.xhtml new file mode 100644 index 00000000..96eb227a --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/PHP-ASP_tags.xhtml @@ -0,0 +1,7 @@ +

    I am going with the same as Markdown.pl 1.0.2b8 here. However I reserve the right to also leave Template toolkit alone at a later date if I need to..

    + +<%foo ok %> + + + +

    [% template_toolkit %]

    diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Unicode.json b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Unicode.json new file mode 100644 index 00000000..2321f0cb --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Unicode.json @@ -0,0 +1,3 @@ +["html", ["blockquote", ["p", "Fo—o"]], + ["p", "μορεοϋερ"], + ["blockquote", ["p", "ßåř"]]] diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Unicode.text b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Unicode.text new file mode 100644 index 00000000..4b63bea8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Unicode.text @@ -0,0 +1,5 @@ +> Fo—o + +μορεοϋερ + +> ßåř diff --git a/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Unicode.xhtml b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Unicode.xhtml new file mode 100644 index 00000000..ca06ddde --- /dev/null +++ b/node_modules/markdown/test/fixtures/Text-Markdown.mdtest/Unicode.xhtml @@ -0,0 +1,9 @@ +
    +

    Fo—o

    +
    + +

    μορεοϋερ

    + +
    +

    ßåř

    +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/abbreviations.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/abbreviations.html new file mode 100644 index 00000000..b6707854 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/abbreviations.html @@ -0,0 +1,3 @@ +

    The HTML specification is maintained by the W3C.

    + +

    Operation Tigra Genesis is going well.

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/abbreviations.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/abbreviations.json new file mode 100644 index 00000000..13a8f30a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/abbreviations.json @@ -0,0 +1,8 @@ +["html", ["p", "The ", ["abbr", { + "title": "Hyper Text Markup Language" +}, +"HTML"], " specification is maintained by the ", ["abbr", { + "title": "World Wide Web Consortium" +}, +"W3C"], "."], + ["p", "Operation ", ["abbr", "Tigra Genesis"], " is going well."]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/abbreviations.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/abbreviations.text new file mode 100644 index 00000000..65513132 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/abbreviations.text @@ -0,0 +1,11 @@ + +The HTML specification is maintained by the W3C. + +*[HTML]: Hyper Text Markup Language +*[W3C]: World Wide Web Consortium + + + +Operation Tigra Genesis is going well. + +*[Tigra Genesis]: diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/alt.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/alt.html new file mode 100644 index 00000000..d4f1d317 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/alt.html @@ -0,0 +1 @@ +

    bar

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/alt.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/alt.json new file mode 100644 index 00000000..dace1253 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/alt.json @@ -0,0 +1,4 @@ +["html", ["p", ["img", { + "src": "/foo.jpg", + "alt": "bar" +}]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/alt.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/alt.text new file mode 100644 index 00000000..915c68f6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/alt.text @@ -0,0 +1,3 @@ + ![bar](/foo.jpg) + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/blank.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blank.html new file mode 100644 index 00000000..f735d039 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blank.html @@ -0,0 +1,3 @@ +

    Linea 1

    + +

    Linea 2

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/blank.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blank.json new file mode 100644 index 00000000..92f93943 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blank.json @@ -0,0 +1,2 @@ +["html", ["p", "Linea 1"], + ["p", "Linea 2"]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/blank.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blank.text new file mode 100644 index 00000000..e065a122 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blank.text @@ -0,0 +1,4 @@ + +Linea 1 + +Linea 2 diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/blanks_in_code.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blanks_in_code.html new file mode 100644 index 00000000..a4ef5db6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blanks_in_code.html @@ -0,0 +1,16 @@ +

    This block is composed of three lines:

    + +
    one
    +
    +three
    + +

    This block is composed of 5

    + +
    one
    +
    +
    +four
    + +

    This block is composed of 2

    + +
    two
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/blanks_in_code.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blanks_in_code.json new file mode 100644 index 00000000..8e405c38 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blanks_in_code.json @@ -0,0 +1,6 @@ +["html", ["p", "This block is composed of three lines:"], + ["pre", ["code", "one\u000a\u000athree"]], + ["p", "This block is composed of 5"], + ["pre", ["code", "one\u000a\u000a\u000afour"]], + ["p", "This block is composed of 2"], + ["pre", ["code", "two"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/blanks_in_code.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blanks_in_code.text new file mode 100644 index 00000000..0f2d7c32 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/blanks_in_code.text @@ -0,0 +1,22 @@ +This block is composed of three lines: + + one + + three + +This block is composed of 5 + + + one + + + four + + +This block is composed of 2 + + + two + + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_def.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_def.html new file mode 100644 index 00000000..ba6f60cf --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_def.html @@ -0,0 +1 @@ +

    test:

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_def.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_def.json new file mode 100644 index 00000000..b2431e6b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_def.json @@ -0,0 +1 @@ +["html", ["p", ["span", "test"], ":"]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_def.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_def.text new file mode 100644 index 00000000..84893556 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_def.text @@ -0,0 +1,2 @@ +[test][]: + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_table.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_table.html new file mode 100644 index 00000000..ae940521 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_table.html @@ -0,0 +1,3 @@ +

    hello

    + +
    hh
    c1c2
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_table.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_table.json new file mode 100644 index 00000000..ec42d74c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_table.json @@ -0,0 +1,20 @@ +["html", ["p", { + "class": "class1", + "style": "color:red" +}, +"hello"], "\u000a", ["table", { + "class": "class1", + "summary": "Table summary", + "style": "color:red" +}, +["thead", ["tr", ["th", "h"], + ["th", "h"]]], + ["tbody", ["tr", ["th", { + "scope": "row", + "style": "text-align: left;" + }, + " c1"], + ["td", { + "style": "text-align: left;" + }, + "c2"]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_table.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_table.text new file mode 100644 index 00000000..f18d1b8f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/bug_table.text @@ -0,0 +1,13 @@ + + +hello +{: summary="Table summary" .class1 style="color:red"} + +h | h +----------|-- +{:t} c1 | c2 +{: summary="Table summary" .class1 style="color:red"} + + + +{:t: scope="row"} diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/code.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code.html new file mode 100644 index 00000000..a20950b8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code.html @@ -0,0 +1,6 @@ +

    Here is an example of AppleScript:

    + +
    tell application "Foo"
    +    beep
    +end tell
    +	tab
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/code.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code.json new file mode 100644 index 00000000..d0084202 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code.json @@ -0,0 +1,2 @@ +["html", ["p", "Here is an example of AppleScript:"], + ["pre", ["code", "tell application \"Foo\"\u000a beep\u000aend tell\u000a\u0009tab"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/code.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code.text new file mode 100644 index 00000000..3656212a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code.text @@ -0,0 +1,7 @@ +Here is an example of AppleScript: + + tell application "Foo" + beep + end tell + tab + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/code2.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code2.html new file mode 100644 index 00000000..9401dba5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code2.html @@ -0,0 +1,5 @@ +
    +

    Code

    + +
    Ciao
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/code2.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code2.json new file mode 100644 index 00000000..3ea22754 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code2.json @@ -0,0 +1,2 @@ +["html", ["blockquote", ["p", "Code"], + ["pre", ["code", "Ciao"]]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/code2.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code2.text new file mode 100644 index 00000000..3f4ea501 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code2.text @@ -0,0 +1,3 @@ +> Code +> +> Ciao diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/code3.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code3.html new file mode 100644 index 00000000..655a9522 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code3.html @@ -0,0 +1,15 @@ +

    This is code (4 spaces):

    + +
    Code
    + +

    This is not code

    + +
    Code
    + +

    This is code (1 tab):

    + +
    Code
    + +

    This is not code

    + +
    Code
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/code3.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code3.json new file mode 100644 index 00000000..d7f3dc1a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code3.json @@ -0,0 +1,8 @@ +["html", ["p", "This is code (4 spaces):"], + ["pre", ["code", "Code"]], + ["p", "This is not code"], + ["pre", ["code", "Code"]], + ["p", "This is code (1 tab):"], + ["pre", ["code", "Code"]], + ["p", "This is not code"], + ["pre", ["code", "Code"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/code3.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code3.text new file mode 100644 index 00000000..2e7c6525 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/code3.text @@ -0,0 +1,17 @@ + +This is code (4 spaces): + + Code +This is not code + + Code + +This is code (1 tab): + + Code +This is not code + + Code + + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/convert.pl b/node_modules/markdown/test/fixtures/docs-maruku-unittest/convert.pl new file mode 100644 index 00000000..20346c86 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/convert.pl @@ -0,0 +1,47 @@ +use strict; +use warnings; +open(LS, "ls -1 *.md|") or die; +my @list = ; +close(LS); + +foreach (@list) { + chomp; + s/\.md$//; + my ($markdown, $html) = convert_to_perl_test("$_.md"); + open(MD, ">$_.text") or die; + print MD $markdown; + close(MD); + open(MD, ">$_.html") or die; + print MD $html; + close(MD); +} + +sub convert_to_perl_test { + my ($file) = @_; + my $FH; + open($FH, '<', $file) or die("Cannot open $file"); + my ($markdown, $html); + my @lines = <$FH>; + close($FH); + my $mode = 0; + foreach my $l (@lines) { + if ($l =~ /^\*\*\*/) { + $mode = 0; + if ($l =~ /Markdown input/i) { + $mode = 1; + } + if ($l =~ /Output of to_html/) { + $mode = 2; + } + } + elsif ($mode > 0) { + if (1 == $mode) { + $markdown .= $l; + } + else { + $html .= $l; + } + } + } + return ($markdown, $html); +} diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/data_loss.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/data_loss.html new file mode 100644 index 00000000..32463a97 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/data_loss.html @@ -0,0 +1,3 @@ +
      +
    1. abcd efgh ijkl
    2. +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/data_loss.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/data_loss.json new file mode 100644 index 00000000..453cb50d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/data_loss.json @@ -0,0 +1 @@ +["html", ["ol", ["li", "abcd efgh ijkl"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/data_loss.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/data_loss.text new file mode 100644 index 00000000..a353aeb1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/data_loss.text @@ -0,0 +1,4 @@ +1. abcd +efgh +ijkl + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/easy.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/easy.html new file mode 100644 index 00000000..8649e556 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/easy.html @@ -0,0 +1 @@ +

    Hello! how are you?

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/easy.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/easy.json new file mode 100644 index 00000000..a4ae99de --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/easy.json @@ -0,0 +1 @@ +["html", ["p", ["em", "Hello!"], " how are ", ["strong", "you"], "?"]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/easy.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/easy.text new file mode 100644 index 00000000..d5ad50c0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/easy.text @@ -0,0 +1 @@ +*Hello!* how are **you**? diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/email.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/email.html new file mode 100644 index 00000000..fe1000d7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/email.html @@ -0,0 +1 @@ +

    This is an email address: andrea@invalid.it

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/email.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/email.json new file mode 100644 index 00000000..6cb0b7a0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/email.json @@ -0,0 +1,4 @@ +["html", ["p", "This is an email address: ", ["a", { + "href": "mailto:andrea@invalid.it" +}, +"andrea@invalid.it"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/email.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/email.text new file mode 100644 index 00000000..4d154e4d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/email.text @@ -0,0 +1,4 @@ + + +This is an email address: + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/entities.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/entities.html new file mode 100644 index 00000000..94239c6b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/entities.html @@ -0,0 +1,14 @@ +

    Maruku translates HTML entities to the equivalent in LaTeX:

    + + + + + +
    EntityResult
    &copy;©
    &pound;£
    a&nbsp;ba b
    &lambda;λ
    &mdash;
    +

    Entity-substitution does not happen in code blocks or inline code.

    + +

    The following should not be translated:

    + +
    &copy;
    + +

    It should read just like this: &copy;.

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/entities.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/entities.json new file mode 100644 index 00000000..cd485373 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/entities.json @@ -0,0 +1,45 @@ +["html", ["p", "Maruku translates HTML entities to the equivalent in LaTeX:"], "\u000a", ["table", ["thead", ["tr", ["th", "Entity"], + ["th", "Result"]]], + ["tbody", ["tr", ["td", { + "style": "text-align: left;" + }, + ["code", "©"]], + ["td", { + "style": "text-align: left;" + }, + "©"]], + ["tr", ["td", { + "style": "text-align: left;" + }, + ["code", "£"]], + ["td", { + "style": "text-align: left;" + }, + "£"]], + ["tr", ["td", { + "style": "text-align: left;" + }, + ["code", "a b"]], + ["td", { + "style": "text-align: left;" + }, + "a b"]], + ["tr", ["td", { + "style": "text-align: left;" + }, + ["code", "λ"]], + ["td", { + "style": "text-align: left;" + }, + "λ"]], + ["tr", ["td", { + "style": "text-align: left;" + }, + ["code", "—"]], + ["td", { + "style": "text-align: left;" + }, + "—"]]]], "\u000a", ["p", "Entity-substitution does not happen in code blocks or inline code."], + ["p", "The following should not be translated:"], + ["pre", ["code", "©"]], + ["p", "It should read just like this: ", ["code", "©"], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/entities.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/entities.text new file mode 100644 index 00000000..7ad0b9e6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/entities.text @@ -0,0 +1,20 @@ +Maruku translates HTML entities to the equivalent in LaTeX: + +Entity | Result +------------|---------- +`©` | © +`£` | £ +`a b` | a b +`λ` | λ +`—` | — + + +Entity-substitution does not happen in code blocks or inline code. + +The following should not be translated: + + © + +It should read just like this: `©`. + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/escaping.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/escaping.html new file mode 100644 index 00000000..165a7844 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/escaping.html @@ -0,0 +1,9 @@ +

    Hello: ! ! ` { } [ ] ( ) # . ! * * *

    + +

    Ora, emphasis, bold, * <- due asterischi-> * , un underscore-> _ , emphasis, incrediblee!

    + +

    This is Code with a special: -> ` <-(after)

    + +

    Start of paragraph

    + +

    End of paragraph

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/escaping.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/escaping.json new file mode 100644 index 00000000..d0d2cbc5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/escaping.json @@ -0,0 +1,5 @@ +["html", ["p", "Hello: ! ! ` { } [ ] ( ) # . ! * * *"], + ["p", "Ora, ", ["em", "emphasis"], ", ", ["strong", "bold"], ", * <- due asterischi-> * , un underscore-> _ , ", ["em", "emphasis"], ", incre", ["em", "dible"], "e!"], + ["p", "This is ", ["code", "Code with a special: -> ` <-"], "(after)"], + ["p", ["code", "Start "], " of paragraph"], + ["p", "End of ", ["code", "paragraph "]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/escaping.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/escaping.text new file mode 100644 index 00000000..ff043c2a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/escaping.text @@ -0,0 +1,11 @@ + Hello: ! \! \` \{ \} \[ \] \( \) \# \. \! * \* * + + +Ora, *emphasis*, **bold**, * <- due asterischi-> * , un underscore-> _ , _emphasis_, + incre*dible*e! + +This is ``Code with a special: -> ` <- ``(after) + +`Start ` of paragraph + +End of `paragraph ` diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_dl.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_dl.html new file mode 100644 index 00000000..f66d4da3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_dl.html @@ -0,0 +1,9 @@ +
    +
    Apple
    + +
    Pomaceous fruit of plants of the genus Malus in the family Rosaceae.
    + +
    Orange
    + +
    The fruit of an evergreen tree of the genus Citrus.
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_dl.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_dl.json new file mode 100644 index 00000000..f54ed0f4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_dl.json @@ -0,0 +1,4 @@ +["html", ["dl", ["dt", "Apple"], + ["dd", "Pomaceous fruit of plants of the genus Malus in the family Rosaceae."], + ["dt", "Orange"], + ["dd", "The fruit of an evergreen tree of the genus Citrus."]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_dl.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_dl.text new file mode 100644 index 00000000..e9c01dc8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_dl.text @@ -0,0 +1,10 @@ +CSS: style.css + + +Apple +: Pomaceous fruit of plants of the genus Malus in + the family Rosaceae. + +Orange +: The fruit of an evergreen tree of the genus Citrus. + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_header_id.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_header_id.html new file mode 100644 index 00000000..20ca1f63 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_header_id.html @@ -0,0 +1,9 @@ +

    Header 1

    + +

    Header 2

    + +

    Header 3

    + +

    Then you can create links to different parts of the same document like this:

    + +

    Link back to header 1, Link back to header 2, Link back to header 3

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_header_id.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_header_id.json new file mode 100644 index 00000000..87e879d8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_header_id.json @@ -0,0 +1,20 @@ +["html", ["h1", { + "id": "header1" +}, +"Header 1"], "\u000a\u000a", ["h2", { + "id": "header2" +}, +"Header 2"], "\u000a\u000a", ["h3", { + "id": "header3" +}, +"Header 3"], "\u000a\u000a", ["p", "Then you can create links to different parts of the same document like this:"], + ["p", ["a", { + "href": "#header1" + }, + "Link back to header 1"], ", ", ["a", { + "href": "#header2" + }, + "Link back to header 2"], ", ", ["a", { + "href": "#header3" + }, + "Link back to header 3"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_header_id.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_header_id.text new file mode 100644 index 00000000..969f9477 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_header_id.text @@ -0,0 +1,14 @@ +Header 1 {#header1} +======== + +Header 2 {#header2} +-------- + +### Header 3 ### {#header3} + +Then you can create links to different parts of the same document like this: + +[Link back to header 1](#header1), +[Link back to header 2](#header2), +[Link back to header 3](#header3) + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_table1.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_table1.html new file mode 100644 index 00000000..4c780de3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_table1.html @@ -0,0 +1,3 @@ + + +
    First HeaderSecond Header
    Content CellContent Cell
    Content CellContent Cell
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_table1.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_table1.json new file mode 100644 index 00000000..e635b2c6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_table1.json @@ -0,0 +1,18 @@ +["html", ["table", ["thead", ["tr", ["th", "First Header"], + ["th", "Second Header"]]], + ["tbody", ["tr", ["td", { + "style": "text-align: left;" + }, + "Content Cell"], + ["td", { + "style": "text-align: left;" + }, + "Content Cell"]], + ["tr", ["td", { + "style": "text-align: left;" + }, + "Content Cell"], + ["td", { + "style": "text-align: left;" + }, + "Content Cell"]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_table1.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_table1.text new file mode 100644 index 00000000..769c7e7c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/extra_table1.text @@ -0,0 +1,7 @@ +CSS: style.css + +First Header | Second Header +------------- | ------------- +Content Cell | Content Cell +Content Cell | Content Cell + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/footnotes.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/footnotes.html new file mode 100644 index 00000000..17d1a8fa --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/footnotes.html @@ -0,0 +1,14 @@ +

    That’s some text with a footnote 1 and another 2 and another 3.

    + +

    This is not a footnote.

    +

    1. +

      And that’s the footnote. This is second sentence (same paragraph).

      +
    2. +

      This is the very long one.

      + +

      That’s the second paragraph.

      +
    3. +

      And that’s the footnote.

      + +

      That’s the second paragraph of the footnote.

      +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/footnotes.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/footnotes.json new file mode 100644 index 00000000..a105cde2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/footnotes.json @@ -0,0 +1,52 @@ +["html", ["p", "That’s some text with a footnote ", ["sup", { + "id": "fnref:1" +}, +["a", { + "href": "#fn:1", + "rel": "footnote" +}, +"1"]], " and another ", ["sup", { + "id": "fnref:2" +}, +["a", { + "href": "#fn:2", + "rel": "footnote" +}, +"2"]], " and another ", ["sup", { + "id": "fnref:3" +}, +["a", { + "href": "#fn:3", + "rel": "footnote" +}, +"3"]], "."], + ["p", "This is not a footnote."], "\u000a", ["div", { + "class": "footnotes" +}, +["hr"], + ["ol", ["li", { + "id": "fn:1" + }, + ["p", "And that’s the footnote. This is second sentence (same paragraph)."], "\u000a", ["a", { + "href": "#fnref:1", + "rev": "footnote" + }, + "↩"]], + ["li", { + "id": "fn:2" + }, + ["p", "This is the very long one."], + ["p", "That’s the second paragraph."], "\u000a", ["a", { + "href": "#fnref:2", + "rev": "footnote" + }, + "↩"]], + ["li", { + "id": "fn:3" + }, + ["p", "And that’s the footnote."], + ["p", "That’s the second paragraph of the footnote."], "\u000a", ["a", { + "href": "#fnref:3", + "rev": "footnote" + }, + "↩"]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/footnotes.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/footnotes.text new file mode 100644 index 00000000..05c6f99f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/footnotes.text @@ -0,0 +1,17 @@ +That's some text with a footnote [^b] and another [^c] and another [^a]. + +[^a]: And that's the footnote. + + That's the second paragraph of the footnote. + + +[^b]: And that's the footnote. +This is second sentence (same paragraph). + +[^c]: + This is the very long one. + + That's the second paragraph. + + +This is not a footnote. diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/headers.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/headers.html new file mode 100644 index 00000000..b6d3893d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/headers.html @@ -0,0 +1,5 @@ +

    A title with emphasis

    + +

    A title with emphasis

    + +

    A title with emphasis

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/headers.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/headers.json new file mode 100644 index 00000000..27b0a89a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/headers.json @@ -0,0 +1,10 @@ +["html", ["h1", { + "id": "a_title_with_emphasis" +}, +"A title with ", ["em", "emphasis"]], "\u000a\u000a", ["h2", { + "id": "a_title_with_emphasis" +}, +"A title with ", ["em", "emphasis"]], "\u000a\u000a", ["h4", { + "id": "a_title_with_emphasis" +}, +"A title with ", ["em", "emphasis"]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/headers.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/headers.text new file mode 100644 index 00000000..387d4e9c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/headers.text @@ -0,0 +1,11 @@ +A title with *emphasis* +======================= + +A title with *emphasis* +----------------------- + + +#### A title with *emphasis* #### + + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/hex_entities.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hex_entities.html new file mode 100644 index 00000000..8741bcc0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hex_entities.html @@ -0,0 +1 @@ +

    Examples of numeric character references include © or © for the copyright symbol, Α or Α for the Greek capital letter alpha, and ا or ا for the Arabic letter alef.

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/hex_entities.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hex_entities.json new file mode 100644 index 00000000..7b347d0e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hex_entities.json @@ -0,0 +1 @@ +["html", ["p", "Examples of numeric character references include © or © for the copyright symbol, Α or Α for the Greek capital letter alpha, and ا or ا for the Arabic letter alef."]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/hex_entities.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hex_entities.text new file mode 100644 index 00000000..98d3bfcd --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hex_entities.text @@ -0,0 +1,3 @@ +Examples of numeric character references include © or © for the copyright symbol, Α or Α for the Greek capital letter alpha, and ا or ا for the Arabic letter alef. + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/hrule.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hrule.html new file mode 100644 index 00000000..b856afba --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hrule.html @@ -0,0 +1 @@ +




    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/hrule.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hrule.json new file mode 100644 index 00000000..7541e6a3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hrule.json @@ -0,0 +1,5 @@ +["html", ["hr"], + ["hr"], + ["hr"], + ["hr"], + ["hr"], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/hrule.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hrule.text new file mode 100644 index 00000000..8ccef4e8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/hrule.text @@ -0,0 +1,2 @@ +* * * + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html2.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html2.html new file mode 100644 index 00000000..1c93e7cf --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html2.html @@ -0,0 +1,2 @@ +

    One

    123

    +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html2.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html2.json new file mode 100644 index 00000000..301489fe --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html2.json @@ -0,0 +1 @@ +["html", ["p", "One ", ["div"], "123"], "\u000a", ["div"], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html2.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html2.text new file mode 100644 index 00000000..58510e22 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html2.text @@ -0,0 +1,4 @@ +One +
    123 + +
    123 diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html3.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html3.html new file mode 100644 index 00000000..8ca3d062 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html3.html @@ -0,0 +1 @@ +

    taking part in some arcane conspirations which involve coffee, robots, sushi,

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html3.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html3.json new file mode 100644 index 00000000..8e7968c4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html3.json @@ -0,0 +1,13 @@ +["html", ["p", "taking part in ", ["a", { + "href": "http://sied.dis.uniroma1.it/" +}, +"some arcane conspirations"], " which involve ", ["b", { + "href": "http://www.flickr.com/photos/censi/70893277/" +}, +"coffee"], ", ", ["a", { + "href": "http://flickr.com/photos/censi/42775664/in/set-936677/" +}, +"robots"], ", ", ["a", { + "href": "http://www.flickr.com/photos/censi/42775888/in/set-936677/" +}, +"sushi"], ","]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html3.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html3.text new file mode 100644 index 00000000..e742017f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html3.text @@ -0,0 +1,5 @@ +taking part in some arcane conspirations which +involve coffee, +robots, +sushi, + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html4.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html4.html new file mode 100644 index 00000000..1b9c5a3d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html4.html @@ -0,0 +1,3 @@ +
    + +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html4.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html4.json new file mode 100644 index 00000000..25f5993d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html4.json @@ -0,0 +1,11 @@ +["html", ["div", { + "class": "frame" +}, +"\u000a\u0009", ["a", { + "href": "http://www.flickr.com/photos/censi/54757256/", + "class": "photo" +}, +["img", { + "src": "http://static.flickr.com/27/54757256_1a2c1d2a95_m.jpg", + "moz-do-not-send": "true" +}]], "\u000a"], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html4.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html4.text new file mode 100644 index 00000000..fc9c0282 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html4.text @@ -0,0 +1,7 @@ +
    + +
    + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html5.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html5.html new file mode 100644 index 00000000..8ffffe20 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html5.html @@ -0,0 +1,3 @@ +
    + Aperitif +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html5.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html5.json new file mode 100644 index 00000000..796883b2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html5.json @@ -0,0 +1,14 @@ +["html", ["div", { + "class": "frame" +}, +"\u000a ", ["a", { + "href": "http://www.flickr.com/photos/censi/88561568/", + "class": "photo" +}, +["img", { + "src": "http://static.flickr.com/28/88561568_ab84d28245_m.jpg", + "height": "180", + "moz-do-not-send": "true", + "alt": "Aperitif", + "width": "240" +}]], "\u000a "], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/html5.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html5.text new file mode 100644 index 00000000..5adc250a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/html5.text @@ -0,0 +1,5 @@ +
    + Aperitif +
    + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/ie.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/ie.html new file mode 100644 index 00000000..2809bfd1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/ie.html @@ -0,0 +1,9 @@ +

    <p>here's an apostrophe & a quote "</p>

    + +
    <p>here's an apostrophe & a quote "</p>
    + +
    <p>here's an apostrophe & a quote "</p>
    + +
    <p>here's an apostrophe & a quote "</p>
    + +
    <p>here's an apostrophe & a quote "</p>
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/ie.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/ie.json new file mode 100644 index 00000000..1ac3f5df --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/ie.json @@ -0,0 +1,42 @@ +["html", ["p", ["code", "

    here's an apostrophe & a quote \"

    "]], + ["pre", ["code", "

    here's an apostrophe & a quote \"

    "]], + ["pre", { + "lang": "xml" + }, + ["code", { + "class": "xml", + "lang": "xml" + }, + "

    here's an apostrophe & a quote \"

    "]], + ["pre", ["code", { + "class": "not_supported", + "lang": "not_supported" + }, + "

    here's an apostrophe & a quote \"

    "]], + ["pre", ["code", { + "class": "xml", + "lang": "xml" + }, + ["span", { + "class": "punct" + }, + "<"], + ["span", { + "class": "tag" + }, + "p"], + ["span", { + "class": "punct" + }, + ">"], "here's an apostrophe & a quote \"", ["span", { + "class": "punct" + }, + ""]]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/ie.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/ie.text new file mode 100644 index 00000000..7a4cfab0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/ie.text @@ -0,0 +1,15 @@ +`

    here's an apostrophe & a quote "

    ` + +

    here's an apostrophe & a quote "

    +{:} + +

    here's an apostrophe & a quote "

    +{:lang=xml} + +

    here's an apostrophe & a quote "

    +{:html_use_syntax=true lang=not_supported} + +

    here's an apostrophe & a quote "

    +{:html_use_syntax=true lang=xml} + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/images.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images.html new file mode 100644 index 00000000..a40a8049 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images.html @@ -0,0 +1,9 @@ +

    This page does not uilizes Cascading Style Sheets

    + +

    Please mouseover to see the title: Cascading Style Sheets

    + +

    Please mouseover to see the title: Cascading Style Sheets

    + +

    I’ll say it one more time: this page does not use Cascading Style Sheets

    + +

    This is double size: Cascading Style Sheets

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/images.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images.json new file mode 100644 index 00000000..cf315e56 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images.json @@ -0,0 +1,20 @@ +["html", ["p", "This page does not uilizes ", ["img", { + "src": "http://jigsaw.w3.org/css-validator/images/vcss", + "alt": "Cascading Style Sheets" +}]], + ["p", "Please mouseover to see the title: ", ["img", { + "src": "http://jigsaw.w3.org/css-validator/images/vcss", + "alt": "Cascading Style Sheets" + }]], + ["p", "Please mouseover to see the title: ", ["img", { + "src": "http://jigsaw.w3.org/css-validator/images/vcss", + "alt": "Cascading Style Sheets" + }]], + ["p", "I’ll say it one more time: this page does not use ", ["img", { + "src": "http://jigsaw.w3.org/css-validator/images/vcss", + "alt": "Cascading Style Sheets" + }]], + ["p", "This is double size: ", ["img", { + "src": "http://jigsaw.w3.org/css-validator/images/vcss", + "alt": "Cascading Style Sheets" + }]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/images.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images.text new file mode 100644 index 00000000..75693619 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images.text @@ -0,0 +1,22 @@ + +This page does not uilizes ![Cascading Style Sheets](http://jigsaw.w3.org/css-validator/images/vcss) + + +Please mouseover to see the title: ![Cascading Style Sheets](http://jigsaw.w3.org/css-validator/images/vcss "Title ok!") + +Please mouseover to see the title: ![Cascading Style Sheets](http://jigsaw.w3.org/css-validator/images/vcss 'Title ok!') + + +I'll say it one more time: this page does not use ![Cascading Style Sheets] [css] + +This is double size: ![Cascading Style Sheets] [css2] + + + +[css]: http://jigsaw.w3.org/css-validator/images/vcss "Optional title attribute" + +[css2]: http://jigsaw.w3.org/css-validator/images/vcss "Optional title attribute" class=external + style="border:0;width:188px;height:131px" + + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/images2.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images2.html new file mode 100644 index 00000000..ad36dd00 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images2.html @@ -0,0 +1,3 @@ +

    This is an image.

    + +

    This is an image.

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/images2.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images2.json new file mode 100644 index 00000000..038186cb --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images2.json @@ -0,0 +1,8 @@ +["html", ["p", "This is an ", ["img", { + "src": "image.jpg", + "alt": "image" +}], "."], + ["p", "This is an ", ["img", { + "src": "image.jpg", + "alt": "image" + }], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/images2.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images2.text new file mode 100644 index 00000000..ef97f4b3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/images2.text @@ -0,0 +1,7 @@ + +This is an ![image][]. + +This is an ![image]. + +[image]: image.jpg + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html.html new file mode 100644 index 00000000..71e7f08f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html.html @@ -0,0 +1,66 @@ +

    Input:

    + +
    <em>Emphasis</em>
    + +

    Result: Emphasis

    + +

    Input:

    + +
    <img src="http://jigsaw.w3.org/css-validator/images/vcss"/>
    + +

    Result on span:

    + +

    Result alone:

    + +

    Without closing:

    +
    +

    +

    This is

    + +

    true

    +
    +

    markdown text (paragraph)

    +

    +

    +

    +

    This is

    + +

    true

    +
    +

    markdown text (no paragraph)

    +

    +

    +

    +

    +

    This is

    + +

    true

    +
    +

    markdown text (block paragraph)

    +

    +

    +
    + + + + +
    +

    This is

    + +

    true

    +
    +

    markdown text. (no par)

    +
    +

    This is

    + +

    true

    +
    +

    markdown text. (par)

    +
    +

    The following is invalid HTML, and will generate an error:

    +
    HTML parse error: 
    +<table>
    +<td markdown="1">This is *true* markdown text. (no par)</td>
    +<td markdown="block">This is *true* markdown text. (par)</td>
    +</tr>
    HTML parse error: 
    +</table>
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html.json new file mode 100644 index 00000000..58c6fa0c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html.json @@ -0,0 +1,28 @@ +["html", ["p", "Input:"], + ["pre", ["code", "Emphasis"]], + ["p", "Result: ", ["em", "Emphasis"]], + ["p", "Input:"], + ["pre", ["code", ""]], + ["p", "Result on span: ", ["img", { + "src": "http://jigsaw.w3.org/css-validator/images/vcss" + }]], + ["p", "Result alone:"], "\u000a", ["img", { + "src": "http://jigsaw.w3.org/css-validator/images/vcss" +}], "\u000a", ["p", "Without closing:"], "\u000a", ["img", { + "src": "http://jigsaw.w3.org/css-validator/images/vcss" +}], + ["div", ["p", ["p", "This is"], "\u000a", ["em", ["p", "true"]], "\u000a", ["p", "markdown text (paragraph)"]], + ["p", ["p", ["p", "This is"], "\u000a", ["em", ["p", "true"]], "\u000a", ["p", "markdown text (no paragraph)"]]], + ["p", ["p", ["p", "This is"], "\u000a", ["em", ["p", "true"]], "\u000a", ["p", "markdown text (block paragraph)"]]]], + ["table", ["tr", ["td", ["p", "This is"], "\u000a", ["em", ["p", "true"]], "\u000a", ["p", "markdown text. (no par)"]], + ["td", ["p", "This is"], "\u000a", ["em", ["p", "true"]], "\u000a", ["p", "markdown text. (par)"]]]], "\u000a", ["p", "The following is invalid HTML, and will generate an error:"], + ["pre", { + "class": "markdown-html-error", + "style": "border: solid 3px red; background-color: pink" + }, + "HTML parse error: \u000a\u000a\u000a\u000a"], + ["pre", { + "class": "markdown-html-error", + "style": "border: solid 3px red; background-color: pink" + }, + "HTML parse error: \u000a
    This is *true* markdown text. (no par)This is *true* markdown text. (par)
    "]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html.text new file mode 100644 index 00000000..ad89f66d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html.text @@ -0,0 +1,50 @@ +CSS: style.css + +Input: + + Emphasis + +Result: Emphasis + +Input: + + + +Result on span: + +Result alone: + + + +Without closing: + + + +
    + This is *true* markdown text (paragraph) + +

    + This is *true* markdown text (no paragraph) +

    +

    + This is *true* markdown text (block paragraph) +

    +
    + + + + + + +
    This is *true* markdown text. (no par)This is *true* markdown text. (par)
    + + +The following is invalid HTML, and will generate an error: + + + + + +
    This is *true* markdown text. (no par)This is *true* markdown text. (par)
    + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html2.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html2.html new file mode 100644 index 00000000..de87541a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html2.html @@ -0,0 +1,3 @@ +
    +

    Test bold

    +

    Test bold

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html2.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html2.json new file mode 100644 index 00000000..441544ec --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html2.json @@ -0,0 +1,2 @@ +["html", ["div", ["p", "Test ", ["strong", "bold"]]], + ["p", "Test ", ["strong", "bold"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html2.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html2.text new file mode 100644 index 00000000..439f930d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/inline_html2.text @@ -0,0 +1,2 @@ +
    Test **bold**
    +

    Test **bold**

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/links.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/links.html new file mode 100644 index 00000000..84254438 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/links.html @@ -0,0 +1,19 @@ +

    Search on Google

    + +

    Search on Google

    + +

    Search on Google

    + +

    Search on Google

    + +

    Search on Google images

    + +

    Inline: Google images

    + +

    Inline with title: Google images

    + +

    Inline with title: Google images

    + +

    Search on http://www.gogole.com or http://Here.com or ask bill@google.com or you might ask bill@google.com.

    + +

    If all else fails, ask Google

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/links.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/links.json new file mode 100644 index 00000000..6cb20e72 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/links.json @@ -0,0 +1,49 @@ +["html", ["p", "Search on ", ["a", { + "href": "http://www.google.com" +}, +"Google"]], + ["p", "Search on ", ["a", { + "href": "http://www.google.com" + }, + "Google"]], + ["p", "Search on ", ["a", { + "href": "http://www.google.com" + }, + "Google"]], + ["p", "Search on ", ["a", { + "href": "http://www.google.com" + }, + "Google"]], + ["p", "Search on ", ["a", { + "href": "http://images.google.com", + "title": "Google images" + }, + "Google images"]], + ["p", "Inline: ", ["a", { + "href": "http://google.com" + }, + "Google images"]], + ["p", "Inline with title: ", ["a", { + "href": "http://google.com", + "title": "Title" + }, + "Google images"]], + ["p", "Inline with title: ", ["a", { + "href": "http://google.com", + "title": "Title" + }, + "Google images"]], + ["p", "Search on ", ["a", { + "href": "http://www.gogole.com" + }, + "http://www.gogole.com"], " or ", ["a", { + "href": "http://Here.com" + }, + "http://Here.com"], " or ask ", ["a", { + "href": "mailto:bill@google.com" + }, + "bill@google.com"], " or you might ask bill@google.com."], + ["p", "If all else fails, ask ", ["a", { + "href": "http://www.google.com" + }, + "Google"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/links.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/links.text new file mode 100644 index 00000000..530f5c05 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/links.text @@ -0,0 +1,36 @@ + +Search on [Google][] + +Search on [Google] [] + +Search on [Google] [google] + +Search on [Google] [Google] + +Search on [Google images][] + +Inline: [Google images](http://google.com) + +Inline with title: [Google images](http://google.com "Title") + +Inline with title: [Google images]( http://google.com "Title" ) + + +Search on or or ask +or you might ask bill@google.com. + +If all else fails, ask [Google](http://www.google.com) + +[google]: http://www.google.com + +[google2]: http://www.google.com 'Single quotes' + +[google3]: http://www.google.com "Double quotes" + +[google4]: http://www.google.com (Parenthesis) + +[Google Search]: + http://www.google.com "Google search" + +[Google Images]: + http://images.google.com (Google images) diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list1.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list1.html new file mode 100644 index 00000000..82824f2d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list1.html @@ -0,0 +1,9 @@ +
      +
    • +

      A list item with a blockquote:

      + +
      +

      This is a blockquote inside a list item.

      +
      +
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list1.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list1.json new file mode 100644 index 00000000..31938140 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list1.json @@ -0,0 +1,2 @@ +["html", ["ul", ["li", ["p", "A list item with a blockquote:"], + ["blockquote", ["p", "This is a blockquote inside a list item."]]]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list1.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list1.text new file mode 100644 index 00000000..c3e37d8e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list1.text @@ -0,0 +1,5 @@ +* A list item with a blockquote: + + > This is a blockquote + > inside a list item. + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list2.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list2.html new file mode 100644 index 00000000..5d180a56 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list2.html @@ -0,0 +1,11 @@ +
      +
    • +

      This is a list item with two paragraphs.

      + +

      This is the second paragraph in the list item. You’re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

      +
    • + +
    • +

      other

      +
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list2.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list2.json new file mode 100644 index 00000000..4d2f14be --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list2.json @@ -0,0 +1,3 @@ +["html", ["ul", ["li", ["p", "This is a list item with two paragraphs."], + ["p", "This is the second paragraph in the list item. You’re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit."]], + ["li", ["p", "other"]]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list2.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list2.text new file mode 100644 index 00000000..c1af1ad8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list2.text @@ -0,0 +1,8 @@ +* This is a list item with two paragraphs. + + This is the second paragraph in the list item. You're +only required to indent the first line. Lorem ipsum dolor +sit amet, consectetuer adipiscing elit. + +* other + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list3.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list3.html new file mode 100644 index 00000000..14600814 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list3.html @@ -0,0 +1,15 @@ +
      +
    • +

      A list item with a blockquote:

      + +
      +

      This is a blockquote inside a list item.

      +
      +
    • + +
    • +

      A list item with a code block:

      + +
      <code goes here>
      +
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list3.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list3.json new file mode 100644 index 00000000..cef3f82e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list3.json @@ -0,0 +1,4 @@ +["html", ["ul", ["li", ["p", "A list item with a blockquote:"], + ["blockquote", ["p", "This is a blockquote inside a list item."]]], + ["li", ["p", "A list item with a code block:"], + ["pre", ["code", ""]]]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list3.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list3.text new file mode 100644 index 00000000..e6333b02 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list3.text @@ -0,0 +1,8 @@ +* A list item with a blockquote: + + > This is a blockquote + > inside a list item. + +* A list item with a code block: + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list4.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list4.html new file mode 100644 index 00000000..45011d03 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list4.html @@ -0,0 +1,19 @@ +

    This is a list:

    + +
      +
    • one
    • + +
    • two
    • +
    + +

    This is not a list: * one ciao

    + +

    This is a list:

    + +
      +
    1. one
    2. + +
    3. two
    4. +
    + +

    This is not a list: 1987. one ciao

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list4.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list4.json new file mode 100644 index 00000000..5a47d291 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list4.json @@ -0,0 +1,8 @@ +["html", ["p", "This is a list:"], + ["ul", ["li", "one"], + ["li", "two"]], + ["p", "This is not a list: * one ciao"], + ["p", "This is a list:"], + ["ol", ["li", "one"], + ["li", "two"]], + ["p", "This is not a list: 1987. one ciao"]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/list4.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list4.text new file mode 100644 index 00000000..0d6e9ce0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/list4.text @@ -0,0 +1,16 @@ +This is a list: +* one +* two + +This is not a list: +* one +ciao + +This is a list: +1. one +1. two + +This is not a list: +1987. one +ciao + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists.html new file mode 100644 index 00000000..c1972b2f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists.html @@ -0,0 +1,39 @@ +
      +
    • Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
    • + +
    • Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
    • + +
    • Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
    • + +
    • Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
    • + +
    • Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
    • +
    + +

    Ancora

    + +
      +
    • +

      This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.

      + +

      ATTENZIONE!

      +
    • + +
    • +

      Suspendisse id sem consectetuer libero luctus adipiscing.

      +
    • +
    + +

    Ancora

    + +
      +
    • +

      This is a list item with two paragraphs.

      + +

      This is the second paragraph in the list item. You’re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

      +
    • + +
    • +

      Another item in the same list.

      +
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists.json new file mode 100644 index 00000000..f14b8704 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists.json @@ -0,0 +1,13 @@ +["html", ["ul", ["li", "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus."], + ["li", "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing."], + ["li", "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing."], + ["li", "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing."], + ["li", "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing."]], + ["p", "Ancora"], + ["ul", ["li", ["p", "This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus."], + ["p", "ATTENZIONE!"]], + ["li", ["p", "Suspendisse id sem consectetuer libero luctus adipiscing."]]], + ["p", "Ancora"], + ["ul", ["li", ["p", "This is a list item with two paragraphs."], + ["p", "This is the second paragraph in the list item. You’re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit."]], + ["li", ["p", "Another item in the same list."]]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists.text new file mode 100644 index 00000000..9c41e9b4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists.text @@ -0,0 +1,32 @@ +* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, + viverra nec, fringilla in, laoreet vitae, risus. +* Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. +* Donec sit amet nisl. Aliquam semper ipsum sit amet velit. +Suspendisse id sem consectetuer libero luctus adipiscing. + * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. +Suspendisse id sem consectetuer libero luctus adipiscing. + * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. + +Ancora + +* This is a list item with two paragraphs. Lorem ipsum dolor + sit amet, consectetuer adipiscing elit. Aliquam hendrerit + mi posuere lectus. + + ATTENZIONE! + +* Suspendisse id sem consectetuer libero luctus adipiscing. + + +Ancora + +* This is a list item with two paragraphs. + + This is the second paragraph in the list item. You're +only required to indent the first line. Lorem ipsum dolor +sit amet, consectetuer adipiscing elit. + +* Another item in the same list. diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists11.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists11.html new file mode 100644 index 00000000..3382952d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists11.html @@ -0,0 +1 @@ +

    - ένα

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists11.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists11.json new file mode 100644 index 00000000..ce496914 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists11.json @@ -0,0 +1 @@ +["html", ["p", "- ένα"]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists11.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists11.text new file mode 100644 index 00000000..54e7ddc7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists11.text @@ -0,0 +1,2 @@ +- ένα + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists6.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists6.html new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists6.html @@ -0,0 +1 @@ + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists6.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists6.json new file mode 100644 index 00000000..39ef51b3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists6.json @@ -0,0 +1 @@ +["html"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists6.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists6.text new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists6.text @@ -0,0 +1 @@ + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7.html new file mode 100644 index 00000000..d42e22af --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7.html @@ -0,0 +1,10 @@ +

    Ciao

    + +
      +
    • Tab * Tab * Tab
    • +
    +

    Ciao

    + +
      +
    • Tab * Tab * Tab
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7.json new file mode 100644 index 00000000..357c2e85 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7.json @@ -0,0 +1,4 @@ +["html", ["p", "Ciao"], + ["ul", ["li", "Tab * Tab * Tab"]], + ["p", "Ciao"], + ["ul", ["li", "Tab * Tab * Tab"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7.text new file mode 100644 index 00000000..67605b1a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7.text @@ -0,0 +1,6 @@ +Ciao + +* Tab + * Tab + * Tab + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7b.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7b.html new file mode 100644 index 00000000..126e133e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7b.html @@ -0,0 +1,31 @@ +
      +
    • +a + +
        +
      • a1
      • + +
      • a2
      • +
      +
    • + +
    • +

      b

      +
    • +
    +-----| WARNING | ----- +
      +
    • +

      a

      + +
        +
      • a1
      • + +
      • a2
      • +
      +
    • + +
    • +

      b

      +
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7b.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7b.json new file mode 100644 index 00000000..5a5bf88b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7b.json @@ -0,0 +1,6 @@ +["html", ["ul", ["li", "\u000aa\u000a\u000a", ["ul", ["li", "a1"], + ["li", "a2"]]], + ["li", ["p", "b"]]], "\u000a-----| WARNING | -----\u000a", ["ul", ["li", ["p", "a"], + ["ul", ["li", "a1"], + ["li", "a2"]]], + ["li", ["p", "b"]]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7b.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7b.text new file mode 100644 index 00000000..c963508f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists7b.text @@ -0,0 +1,6 @@ +* a + * a1 + * a2 +* b + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists8.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists8.html new file mode 100644 index 00000000..de795588 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists8.html @@ -0,0 +1,13 @@ +

    Here is a paragraph.

    + +
      +
    • Item 1
    • + +
    • Item 2
    • + +
    • Item 3
    • +
    +-----| WARNING | ----- +

    Here is a paragraph.

    + +

    * Item 1 * Item 2 * Item 3

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists8.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists8.json new file mode 100644 index 00000000..2332ba23 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists8.json @@ -0,0 +1,5 @@ +["html", ["p", "Here is a paragraph."], + ["ul", ["li", "Item 1"], + ["li", "Item 2"], + ["li", "Item 3"]], "\u000a-----| WARNING | -----\u000a", ["p", "Here is a paragraph."], + ["p", "* Item 1 * Item 2 * Item 3"]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists8.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists8.text new file mode 100644 index 00000000..d11e4a37 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists8.text @@ -0,0 +1,7 @@ +Here is a paragraph. + + + * Item 1 + * Item 2 + * Item 3 + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists9.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists9.html new file mode 100644 index 00000000..29fc1b91 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists9.html @@ -0,0 +1,17 @@ +
      +
    • +

      Due

      + +
        +
      1. tre
      2. + +
      3. tre
      4. + +
      5. tre
      6. +
      +
    • + +
    • +

      Due

      +
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists9.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists9.json new file mode 100644 index 00000000..f91bd749 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists9.json @@ -0,0 +1,5 @@ +["html", ["ul", ["li", ["p", "Due"], + ["ol", ["li", "tre"], + ["li", "tre"], + ["li", "tre"]]], + ["li", ["p", "Due"]]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists9.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists9.text new file mode 100644 index 00000000..68395e8d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists9.text @@ -0,0 +1,5 @@ +- Due + 1. tre + 1. tre + 1. tre +- Due diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_after_paragraph.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_after_paragraph.html new file mode 100644 index 00000000..8b52c96b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_after_paragraph.html @@ -0,0 +1,37 @@ +

    Paragraph, list with no space: * ciao

    + +

    Paragraph, list with 1 space: * ciao

    + +

    Paragraph, list with 3 space: * ciao

    + +

    Paragraph, list with 4 spaces: * ciao

    + +

    Paragraph, list with 1 tab: * ciao

    + +

    Paragraph (1 space after), list with no space: * ciao

    + +

    Paragraph (2 spaces after), list with no space:
    * ciao

    + +

    Paragraph (3 spaces after), list with no space:
    * ciao

    + +

    Paragraph with block quote:

    + +
    +

    Quoted

    +
    + +

    Paragraph with header:

    + + + +

    Paragraph with header on two lines:

    + + + +

    Paragraph with html after

    + +

    Paragraph with html after, indented: Emphasis

    + +

    Paragraph with html after, indented: Emphasis tralla Emph

    + +

    Paragraph with html after, indented: Emphasis *tralla* Emph

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_after_paragraph.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_after_paragraph.json new file mode 100644 index 00000000..3d0e4858 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_after_paragraph.json @@ -0,0 +1,20 @@ +["html", ["p", "Paragraph, list with no space: * ciao"], + ["p", "Paragraph, list with 1 space: * ciao"], + ["p", "Paragraph, list with 3 space: * ciao"], + ["p", "Paragraph, list with 4 spaces: * ciao"], + ["p", "Paragraph, list with 1 tab: * ciao"], + ["p", "Paragraph (1 space after), list with no space: * ciao"], + ["p", "Paragraph (2 spaces after), list with no space:", ["br"], "* ciao"], + ["p", "Paragraph (3 spaces after), list with no space: ", ["br"], "* ciao"], + ["p", "Paragraph with block quote:"], + ["blockquote", ["p", "Quoted"]], + ["p", "Paragraph with header:"], "\u000a\u000a", ["h3", { + "id": "header" +}, +"header"], "\u000a\u000a", ["p", "Paragraph with header on two lines:"], "\u000a\u000a", ["h2", { + "id": "header" +}, +"header"], "\u000a\u000a", ["p", "Paragraph with html after ", ["div"]], + ["p", "Paragraph with html after, indented: ", ["em", "Emphasis"]], + ["p", "Paragraph with html after, indented: ", ["em", "Emphasis"], " ", ["em", "tralla"], " ", ["em", "Emph"]], + ["p", "Paragraph with html after, indented: ", ["em", "Emphasis *tralla* Emph"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_after_paragraph.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_after_paragraph.text new file mode 100644 index 00000000..c0be0c21 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_after_paragraph.text @@ -0,0 +1,45 @@ +Paragraph, list with no space: +* ciao + +Paragraph, list with 1 space: + * ciao + +Paragraph, list with 3 space: + * ciao + +Paragraph, list with 4 spaces: + * ciao + +Paragraph, list with 1 tab: + * ciao + +Paragraph (1 space after), list with no space: +* ciao + +Paragraph (2 spaces after), list with no space: +* ciao + +Paragraph (3 spaces after), list with no space: +* ciao + +Paragraph with block quote: +> Quoted + +Paragraph with header: +### header ### + +Paragraph with header on two lines: +header +------ + + +Paragraph with html after +
    + +Paragraph with html after, indented: + Emphasis + +Paragraph with html after, indented: Emphasis *tralla* Emph + +Paragraph with html after, indented: Emphasis *tralla* Emph + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_ol.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_ol.html new file mode 100644 index 00000000..4820f7d2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_ol.html @@ -0,0 +1,61 @@ +
      +
    1. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
    2. + +
    3. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
    4. + +
    5. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
    6. + +
    7. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
    8. + +
    9. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
    10. +
    + +

    Ancora

    + +
      +
    1. +

      This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.

      + +

      ATTENZIONE!

      + +
        +
      • +

        Uno

        +
      • + +
      • +

        Due

        + +
          +
        1. tre
        2. + +
        3. tre
        4. + +
        5. tre
        6. +
        +
      • + +
      • +

        Due

        +
      • +
      +
    2. + +
    3. +

      Suspendisse id sem consectetuer libero luctus adipiscing.

      +
    4. +
    + +

    Ancora

    + +
      +
    • +

      This is a list item with two paragraphs.

      + +

      This is the second paragraph in the list item. You’re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

      +
    • + +
    • +

      Another item in the same list.

      +
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_ol.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_ol.json new file mode 100644 index 00000000..3de9311e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_ol.json @@ -0,0 +1,19 @@ +["html", ["ol", ["li", "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus."], + ["li", "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing."], + ["li", "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing."], + ["li", "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing."], + ["li", "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing."]], + ["p", "Ancora"], + ["ol", ["li", ["p", "This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus."], + ["p", "ATTENZIONE!"], + ["ul", ["li", ["p", "Uno"]], + ["li", ["p", "Due"], + ["ol", ["li", "tre"], + ["li", "tre"], + ["li", "tre"]]], + ["li", ["p", "Due"]]]], + ["li", ["p", "Suspendisse id sem consectetuer libero luctus adipiscing."]]], + ["p", "Ancora"], + ["ul", ["li", ["p", "This is a list item with two paragraphs."], + ["p", "This is the second paragraph in the list item. You’re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit."]], + ["li", ["p", "Another item in the same list."]]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_ol.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_ol.text new file mode 100644 index 00000000..5b94ea0e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/lists_ol.text @@ -0,0 +1,39 @@ +1. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, + viverra nec, fringilla in, laoreet vitae, risus. + 2. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. +3. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. +Suspendisse id sem consectetuer libero luctus adipiscing. + 3. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. +Suspendisse id sem consectetuer libero luctus adipiscing. + 4. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. + +Ancora + +1. This is a list item with two paragraphs. Lorem ipsum dolor + sit amet, consectetuer adipiscing elit. Aliquam hendrerit + mi posuere lectus. + + ATTENZIONE! + + - Uno + - Due + 1. tre + 1. tre + 1. tre + - Due + +2. Suspendisse id sem consectetuer libero luctus adipiscing. + + +Ancora + +* This is a list item with two paragraphs. + + This is the second paragraph in the list item. You're +only required to indent the first line. Lorem ipsum dolor +sit amet, consectetuer adipiscing elit. + +* Another item in the same list. diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/loss.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/loss.html new file mode 100644 index 00000000..3fc714a3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/loss.html @@ -0,0 +1 @@ +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/loss.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/loss.json new file mode 100644 index 00000000..76a17110 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/loss.json @@ -0,0 +1 @@ +["html", ["br"], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/loss.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/loss.text new file mode 100644 index 00000000..1f94fd6e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/loss.text @@ -0,0 +1,2 @@ +
    123 + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/misc_sw.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/misc_sw.html new file mode 100644 index 00000000..c1a7405e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/misc_sw.html @@ -0,0 +1,79 @@ +

    General

    + +
      +
    • Operating System : Mac OS X: heaven, after the purgatory of Linux and the hell of Windows.
    • + +
    • Browser: Firefox. On a Mac, Camino.
    • + +
    • Email: GMail, “search, don’t sort” really works.
    • + +
    • Text Editor: TextMate, you have to buy it, but it’s worth every penny. There are rumours that it’s been converting (recovering) Emacs users (addicts). Unfortunately, it’s Mac only. An alternative is jedit (GPL, Java).
    • +
    + +

    Development

    + +
      +
    • +

      Build system: cmake, throw the autotools away.

      +
    • + +
    • +

      Source code control system: ditch CVS for subversion.

      +
    • + +
    • +

      Project management: Trac tracks everything.

      +
    • + +
    • +

      Scripting language: Ruby is Japanese pragmatism (and has a poignant guide). Python, you say? Python is too academic and snob:

      + +
      $ python       
      +Python 2.4.1 (\#1, Jun  4 2005, 00:54:33) 
      +Type "help", "copyright", "credits" or "license" for more information.
      +>>> exit
      +'Use Ctrl-D (i.e. EOF) to exit.'
      +>>> quit
      +'Use Ctrl-D (i.e. EOF) to exit.'
      +
    • + +
    • +

      Java IDE: JBuilder is great software and has a free version (IMHO better than Eclipse). Java is not a pain anymore since it gained generics and got opensourced.

      +
    • + +
    • +

      Mark-up language: HTML is so 2001, why don’t you take at look at Markdown? Look at the source of this page.

      +
    • + +
    • +

      C++ libraries: * QT for GUIs. * GSL for math. * Magick++ for manipulating images. * Cairo for creating PDFs. * Boost for just about everything else.

      +
    • +
    + +

    Research

    + +
      +
    • Writing papers: LaTeX
    • + +
    • Writing papers & enjoying the process: LyX
    • + +
    • Handsome figures in your papers: xfig or, better, jfig.
    • + +
    • The occasional presentation with many graphical content: OpenOffice Impress (using the OOOlatex plugin); the alternative is PowerPoint with the TexPoint plugin.
    • + +
    • Managing BibTeX: jabref: multi-platform, for all your bibtex needs.
    • + +
    • IEEExplore and BibTeX: convert citations using BibConverter.
    • +
    + +

    Cool websites

    + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/misc_sw.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/misc_sw.json new file mode 100644 index 00000000..dcf035e6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/misc_sw.json @@ -0,0 +1,139 @@ +["html", ["h3", { + "id": "general" +}, +"General"], "\u000a\u000a", ["ul", ["li", ["em", "Operating System"], " : ", ["a", { + "href": "http://www.apple.com/getamac/" +}, +"Mac OS X"], ": heaven, after the purgatory of Linux and the hell of Windows."], + ["li", ["em", "Browser"], ": ", ["a", { + "href": "http://getfirefox.com/" + }, + "Firefox"], ". On a Mac, ", ["a", { + "href": "http://www.caminobrowser.org/" + }, + "Camino"], "."], + ["li", ["em", "Email"], ": ", ["a", { + "href": "http://gmail.com/" + }, + "GMail"], ", “search, don’t sort” really works."], + ["li", ["em", "Text Editor"], ": ", ["a", { + "href": "http://www.apple.com/getamac/" + }, + "TextMate"], ", you have to buy it, but it’s worth every penny. There are rumours that it’s been converting (recovering) Emacs users (addicts). Unfortunately, it’s Mac only. An alternative is ", ["a", { + "href": "http://www.jedit.org/" + }, + "jedit"], " (GPL, Java)."]], "\u000a\u000a", ["h3", { + "id": "development" +}, +"Development"], "\u000a\u000a", ["ul", ["li", ["p", ["em", "Build system"], ": ", ["a", { + "href": "http://www.cmake.org/" +}, +"cmake"], ", throw the ", ["a", { + "href": "http://sources.redhat.com/autobook/" +}, +"autotools"], " away."]], + ["li", ["p", ["em", "Source code control system"], ": ditch CVS for ", ["a", { + "href": "http://subversion.tigris.org" + }, + "subversion"], "."]], + ["li", ["p", ["em", "Project management"], ": ", ["a", { + "href": "http://trac.edgewall.org/" + }, + "Trac"], " tracks everything."]], + ["li", ["p", ["em", "Scripting language"], ": ", ["a", { + "href": "http://www.ruby-lang.org/" + }, + "Ruby"], " is Japanese pragmatism (and has a ", ["a", { + "href": "http://poignantguide.net/ruby/" + }, + "poignant"], " guide). Python, you say? Python is too academic and snob:"], + ["pre", ["code", "$ python \u000aPython 2.4.1 (\\#1, Jun 4 2005, 00:54:33) \u000aType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\u000a>>> exit\u000a'Use Ctrl-D (i.e. EOF) to exit.'\u000a>>> quit\u000a'Use Ctrl-D (i.e. EOF) to exit.'"]]], + ["li", ["p", ["em", "Java IDE"], ": ", ["a", { + "href": "http://www.borland.com/us/products/jbuilder/index.html" + }, + "JBuilder"], " is great software and has a free version (IMHO better than Eclipse). Java is not a pain anymore since it gained ", ["a", { + "href": "http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html" + }, + "generics"], " and got opensourced."]], + ["li", ["p", ["em", "Mark-up language"], ": HTML is so 2001, why don’t you take at look at ", ["a", { + "href": "http://en.wikipedia.org/wiki/Markdown" + }, + "Markdown"], "? ", ["a", { + "href": "data/misc_markdown.png" + }, + "Look at the source of this page"], "."]], + ["li", ["p", ["em", "C++ libraries"], ": * ", ["a", { + "href": "http://www.trolltech.no/" + }, + "QT"], " for GUIs. * ", ["a", { + "href": "http://www.gnu.org/software/gsl/" + }, + "GSL"], " for math. * ", ["a", { + "href": "http://www.imagemagick.org/Magick++/" + }, + "Magick++"], " for manipulating images. * ", ["a", { + "href": "http://cairographics.org/" + }, + "Cairo"], " for creating PDFs. * ", ["a", { + "href": "http://www.boost.org/" + }, + "Boost"], " for just about everything else."]]], "\u000a\u000a", ["h3", { + "id": "research" +}, +"Research"], "\u000a\u000a", ["ul", ["li", ["em", "Writing papers"], ": ", ["a", { + "href": "http://en.wikipedia.org/wiki/LaTeX" +}, +"LaTeX"]], + ["li", ["em", "Writing papers & enjoying the process"], ": ", ["a", { + "href": "http://www.lyx.org" + }, + "LyX"]], + ["li", ["em", "Handsome figures in your papers"], ": ", ["a", { + "href": "http://www.xfig.org/" + }, + "xfig"], " or, better, ", ["a", { + "href": "http://tams-www.informatik.uni-hamburg.de/applets/jfig/" + }, + "jfig"], "."], + ["li", ["em", "The occasional presentation with many graphical content"], ": ", ["a", { + "href": "http://www.openoffice.org/product/impress.html" + }, + "OpenOffice Impress"], " (using the ", ["a", { + "href": "http://ooolatex.sourceforge.net/" + }, + "OOOlatex plugin"], "); the alternative is PowerPoint with the ", ["a", { + "href": "http://texpoint.necula.org/" + }, + "TexPoint"], " plugin."], + ["li", ["em", "Managing BibTeX"], ": ", ["a", { + "href": "http://jabref.sourceforge.net/" + }, + "jabref"], ": multi-platform, for all your bibtex needs."], + ["li", ["em", "IEEExplore and BibTeX"], ": convert citations using ", ["a", { + "href": "http://www.bibconverter.net/ieeexplore/" + }, + "BibConverter"], "."]], "\u000a\u000a", ["h3", { + "id": "cool_websites" +}, +"Cool websites"], "\u000a\u000a", ["ul", ["li", ["em", "Best site in the wwworld"], ": ", ["a", { + "href": "http://en.wikipedia.org/" +}, +"Wikipedia"]], + ["li", ["a", { + "href": "http://www.mutopiaproject.org/" + }, + "Mutopia"], " for sheet music; ", ["a", { + "href": "http://www.gutenberg.org/" + }, + "the Gutenberg Project"], " for books; ", ["a", { + "href": "http://www.liberliber.it/" + }, + "LiberLiber"], " for books in italian."], + ["li", ["em", "Blogs"], ": ", ["a", { + "href": "http://bloglines.com/" + }, + "Bloglines"]], + ["li", ["em", "Sharing photos"], ": ", ["a", { + "href": "http://www.flickr.com/" + }, + "flickr"], " exposes an API you can use."]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/misc_sw.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/misc_sw.text new file mode 100644 index 00000000..9dab62a9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/misc_sw.text @@ -0,0 +1,106 @@ +Subject: Software not painful to use +Subject_short: painless software +Topic: /misc/coolsw +Archive: no +Date: Nov 20 2006 +Order: -9.5 +inMenu: true + + +### General ### + +* *Operating System* : [Mac OS X][switch]: heaven, after the purgatory of Linux + and the hell of Windows. +* *Browser*: [Firefox][firefox]. On a Mac, [Camino][camino]. +* *Email*: [GMail][gmail], "search, don't sort" really works. +* *Text Editor*: [TextMate][textmate], you have to buy it, but it's worth every + penny. There are rumours that it's been converting (recovering) Emacs + users (addicts). Unfortunately, it's Mac only. An alternative is + [jedit][jedit] (GPL, Java). + +### Development ### + +* *Build system*: [cmake][cmake], throw the [autotools][autotools] away. +* *Source code control system*: ditch CVS for [subversion][subversion]. +* *Project management*: [Trac][trac] tracks everything. +* *Scripting language*: [Ruby][ruby] is Japanese pragmatism (and has a [poignant][poignant] guide). + Python, you say? Python is too academic and snob: + + $ python + Python 2.4.1 (\#1, Jun 4 2005, 00:54:33) + Type "help", "copyright", "credits" or "license" for more information. + >>> exit + 'Use Ctrl-D (i.e. EOF) to exit.' + >>> quit + 'Use Ctrl-D (i.e. EOF) to exit.' + +* *Java IDE*: [JBuilder][jbuilder] is great software and has a free version (IMHO better than Eclipse). Java + is not a pain anymore since it gained [generics][java-generics] and got opensourced. +* *Mark-up language*: HTML is so 2001, why don't you take at look at [Markdown][markdown]? [Look at the source of this page](data/misc_markdown.png). +* *C++ libraries*: + * [QT][qt] for GUIs. + * [GSL][gsl] for math. + * [Magick++][magick] for manipulating images. + * [Cairo][cairo] for creating PDFs. + * [Boost][boost] for just about everything else. + + +### Research ### + +* *Writing papers*: [LaTeX][latex] +* *Writing papers & enjoying the process*: [LyX][lyx] +* *Handsome figures in your papers*: [xfig][xfig] or, better, [jfig][jfig]. +* *The occasional presentation with many graphical content*: + [OpenOffice Impress][impress] (using the [OOOlatex plugin][ooolatex]); + the alternative is PowerPoint with the [TexPoint][texpoint] plugin. +* *Managing BibTeX*: [jabref][jabref]: multi-platform, for all your bibtex needs. +* *IEEExplore and BibTeX*: convert citations using [BibConverter][bibconverter]. + +### Cool websites ### + +* *Best site in the wwworld*: [Wikipedia][wikipedia] +* [Mutopia][mutopia] for sheet music; [the Gutenberg Project][gutenberg] for books; [LiberLiber][liberliber] for books in italian. +* *Blogs*: [Bloglines][bloglines] +* *Sharing photos*: [flickr][flickr] exposes an API you can use. + + +[firefox]: http://getfirefox.com/ +[gmail]: http://gmail.com/ +[bloglines]: http://bloglines.com/ +[wikipedia]: http://en.wikipedia.org/ +[ruby]: http://www.ruby-lang.org/ +[poignant]: http://poignantguide.net/ruby/ +[webgen]: http://webgen.rubyforge.org/ +[markdown]: http://daringfireball.net/projects/markdown/ +[latex]: http://en.wikipedia.org/wiki/LaTeX +[lyx]: http://www.lyx.org +[impress]: http://www.openoffice.org/product/impress.html +[ooolatex]: http://ooolatex.sourceforge.net/ +[texpoint]: http://texpoint.necula.org/ +[jabref]: http://jabref.sourceforge.net/ +[camino]: http://www.caminobrowser.org/ +[switch]: http://www.apple.com/getamac/ +[textmate]: http://www.apple.com/getamac/ +[cmake]: http://www.cmake.org/ +[xfig]: http://www.xfig.org/ +[jfig]: http://tams-www.informatik.uni-hamburg.de/applets/jfig/ +[subversion]: http://subversion.tigris.org +[jbuilder]: http://www.borland.com/us/products/jbuilder/index.html +[flickr]: http://www.flickr.com/ +[myflickr]: http://www.flickr.com/photos/censi +[bibconverter]: http://www.bibconverter.net/ieeexplore/ +[autotools]: http://sources.redhat.com/autobook/ +[jedit]: http://www.jedit.org/ +[qt]: http://www.trolltech.no/ +[gsl]: http://www.gnu.org/software/gsl/ +[magick]: http://www.imagemagick.org/Magick++/ +[cairo]: http://cairographics.org/ +[boost]: http://www.boost.org/ +[markdown]: http://en.wikipedia.org/wiki/Markdown +[trac]: http://trac.edgewall.org/ +[mutopia]: http://www.mutopiaproject.org/ +[liberliber]: http://www.liberliber.it/ +[gutenberg]: http://www.gutenberg.org/ +[java-generics]: http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/olist.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/olist.html new file mode 100644 index 00000000..d349edbe --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/olist.html @@ -0,0 +1,9 @@ +

    This is a list:

    + +
      +
    1. one
    2. + +
    3. two
    4. + +
    5. three
    6. +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/olist.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/olist.json new file mode 100644 index 00000000..a7981316 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/olist.json @@ -0,0 +1,4 @@ +["html", ["p", "This is a list:"], + ["ol", ["li", "one"], + ["li", "two"], + ["li", "three"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/olist.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/olist.text new file mode 100644 index 00000000..e68a6591 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/olist.text @@ -0,0 +1,5 @@ +This is a list: + +2. one +2. two +3. three diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/one.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/one.html new file mode 100644 index 00000000..e38afbae --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/one.html @@ -0,0 +1 @@ +

    One line

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/one.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/one.json new file mode 100644 index 00000000..56c6552b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/one.json @@ -0,0 +1 @@ +["html", ["p", "One line"]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/one.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/one.text new file mode 100644 index 00000000..b8ab5853 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/one.text @@ -0,0 +1 @@ +One line diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraph.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraph.html new file mode 100644 index 00000000..b814fa2b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraph.html @@ -0,0 +1 @@ +

    Paragraph

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraph.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraph.json new file mode 100644 index 00000000..d6f73d0d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraph.json @@ -0,0 +1 @@ +["html", ["p", "Paragraph"]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraph.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraph.text new file mode 100644 index 00000000..94258d1b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraph.text @@ -0,0 +1,2 @@ +Paragraph + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraphs.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraphs.html new file mode 100644 index 00000000..17785330 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraphs.html @@ -0,0 +1,5 @@ +

    Paragraph 1

    + +

    Paragraph 2

    + +

    Paragraph 3 Paragraph 4 Paragraph Br->
    Paragraph 5

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraphs.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraphs.json new file mode 100644 index 00000000..82b87fb7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraphs.json @@ -0,0 +1,3 @@ +["html", ["p", "Paragraph 1"], + ["p", "Paragraph 2"], + ["p", "Paragraph 3 Paragraph 4 Paragraph Br->", ["br"], "Paragraph 5"]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraphs.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraphs.text new file mode 100644 index 00000000..77b5ff8a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/paragraphs.text @@ -0,0 +1,11 @@ +Paragraph 1 + +Paragraph 2 + + +Paragraph 3 +Paragraph 4 +Paragraph Br-> +Paragraph 5 + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/smartypants.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/smartypants.html new file mode 100644 index 00000000..cf0df19d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/smartypants.html @@ -0,0 +1,17 @@ +
    'Twas a "test" to 'remember' in the '90s.
    + +

    ‘Twas a “test” to ‘remember’ in the ’90s.

    + +
    It was --- in a sense --- really... interesting.
    + +

    It was — in a sense — really… interesting.

    + +
    I -- too -- met << some curly quotes >> there or <<here>>No space.
    + +

    I – too – met « some curly quotes » there or «here»No space.

    + +
    She was 6\"12\'.
    + +
    +

    She was 6"12'.

    +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/smartypants.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/smartypants.json new file mode 100644 index 00000000..3ec5f74d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/smartypants.json @@ -0,0 +1,8 @@ +["html", ["pre", ["code", "'Twas a \"test\" to 'remember' in the '90s."]], + ["p", "‘Twas a “test” to ‘remember’ in the ’90s."], + ["pre", ["code", "It was --- in a sense --- really... interesting."]], + ["p", "It was — in a sense — really… interesting."], + ["pre", ["code", "I -- too -- met << some curly quotes >> there or <>No space."]], + ["p", "I – too – met « some curly quotes » there or «here»No space."], + ["pre", ["code", "She was 6\\\"12\\'."]], + ["blockquote", ["p", "She was 6\"12'."]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/smartypants.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/smartypants.text new file mode 100644 index 00000000..14478ea5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/smartypants.text @@ -0,0 +1,13 @@ + 'Twas a "test" to 'remember' in the '90s. +'Twas a "test" to 'remember' in the '90s. + + It was --- in a sense --- really... interesting. +It was --- in a sense --- really... interesting. + + I -- too -- met << some curly quotes >> there or <>No space. +I -- too -- met << some curly quotes >> there or <>No space. + + + She was 6\"12\'. +> She was 6\"12\'. + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/syntax_hl.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/syntax_hl.html new file mode 100644 index 00000000..0c2ac27a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/syntax_hl.html @@ -0,0 +1,11 @@ +

    This is ruby code:

    + +
    require 'maruku'
    +
    +puts Maruku.new($stdin).to_html
    + +

    This is ruby code:

    + +
    require 'maruku'
    + +
    puts Maruku.new($stdin).to_html
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/syntax_hl.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/syntax_hl.json new file mode 100644 index 00000000..3442f4c3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/syntax_hl.json @@ -0,0 +1,23 @@ +["html", ["p", "This is ruby code:"], + ["pre", ["code", "require 'maruku'\u000a\u000aputs Maruku.new($stdin).to_html"]], + ["p", "This is ruby code:"], + ["pre", ["code", { + "class": "ruby", + "lang": "ruby" + }, + ["span", { + "class": "ident" + }, + "require"], " ", ["span", { + "class": "punct" + }, + "'"], + ["span", { + "class": "string" + }, + "maruku"], + ["span", { + "class": "punct" + }, + "'"]]], + ["pre", ["code", "puts Maruku.new($stdin).to_html"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/syntax_hl.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/syntax_hl.text new file mode 100644 index 00000000..ec6d1a41 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/syntax_hl.text @@ -0,0 +1,12 @@ +This is ruby code: + + require 'maruku' + + puts Maruku.new($stdin).to_html + +This is ruby code: + + require 'maruku' +{: lang=ruby html_use_syntax} + + puts Maruku.new($stdin).to_html diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/table_attributes.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/table_attributes.html new file mode 100644 index 00000000..5e6304d7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/table_attributes.html @@ -0,0 +1,2 @@ + +
    hh
    c1c2
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/table_attributes.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/table_attributes.json new file mode 100644 index 00000000..1c004cb1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/table_attributes.json @@ -0,0 +1,22 @@ +["html", ["table", { + "cellspacing": "2em", + "class": "class1", + "border": "3", + "rules": "cols", + "frame": "lhs", + "summary": "Table summary", + "cellpadding": "4px", + "width": "50%", + "style": "color:red" +}, +["thead", ["tr", ["th", "h"], + ["th", "h"]]], + ["tbody", ["tr", ["th", { + "scope": "row", + "style": "text-align: left;" + }, + " c1"], + ["td", { + "style": "text-align: left;" + }, + "c2"]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/table_attributes.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/table_attributes.text new file mode 100644 index 00000000..3dc217d9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/table_attributes.text @@ -0,0 +1,7 @@ + +h | h +----------|-- +{:t} c1 | c2 +{: summary="Table summary" .class1 style="color:red" border=3 width="50%" frame=lhs rules=cols cellspacing=2em cellpadding=4px} + +{:t: scope="row"} diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/test.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/test.html new file mode 100644 index 00000000..84945554 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/test.html @@ -0,0 +1 @@ +
           $ python       
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/test.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/test.json new file mode 100644 index 00000000..f3394ab2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/test.json @@ -0,0 +1 @@ +["html", ["pre", ["code", " $ python "]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/test.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/test.text new file mode 100644 index 00000000..96c7f45f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/test.text @@ -0,0 +1,5 @@ + + $ python + + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/wrapping.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/wrapping.html new file mode 100644 index 00000000..941a5008 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/wrapping.html @@ -0,0 +1,7 @@ +

    Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Break:
    Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet.

    + +
      +
    • Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet Lorem ipsum Break:
      Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet
    • + +
    • Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/wrapping.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/wrapping.json new file mode 100644 index 00000000..d32bcde4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/wrapping.json @@ -0,0 +1,3 @@ +["html", ["p", "Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Break:", ["br"], "Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet."], + ["ul", ["li", "Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet Lorem ipsum Break:", ["br"], "Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet"], + ["li", "Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet"]]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/wrapping.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/wrapping.text new file mode 100644 index 00000000..fcfdd9ad --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/wrapping.text @@ -0,0 +1,8 @@ +Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Break: +Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. + +* Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet + Lorem ipsum Break: + Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet +* Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml.html new file mode 100644 index 00000000..8b39ac89 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml.json new file mode 100644 index 00000000..ca90965e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml.json @@ -0,0 +1,21 @@ +["html", ["svg:svg"], + ["svg:svg", { + "height": "400px", + "width": "600px" + }, + "\u000a ", ["svg:g", { + "id": "group" + }, + "\u000a\u0009", ["svg:circle", { + "cy": "3cm", + "id": "circ1", + "r": "1cm", + "cx": "3cm", + "style": "fill:red;" + }], "\u000a\u0009", ["svg:circle", { + "cy": "3cm", + "id": "circ2", + "r": "1cm", + "cx": "7cm", + "style": "fill:red;" + }], "\u000a "], "\u000a"], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml.text new file mode 100644 index 00000000..98fb57c5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml.text @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml2.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml2.html new file mode 100644 index 00000000..54fef9bc --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml2.html @@ -0,0 +1,3 @@ + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml2.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml2.json new file mode 100644 index 00000000..15ac8a55 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml2.json @@ -0,0 +1 @@ +["html", "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml2.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml2.text new file mode 100644 index 00000000..54fef9bc --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml2.text @@ -0,0 +1,3 @@ + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml3.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml3.html new file mode 100644 index 00000000..92c8a1f2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml3.html @@ -0,0 +1,4 @@ +Blah + + +
    em
    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml3.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml3.json new file mode 100644 index 00000000..7ddefcb5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml3.json @@ -0,0 +1 @@ +["html", ["table", "Blah", ["thead", ["td", ["em", "em"]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml3.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml3.text new file mode 100644 index 00000000..17553e13 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml3.text @@ -0,0 +1,7 @@ + + Blah + + + +
    *em*
    + diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml_instruction.html b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml_instruction.html new file mode 100644 index 00000000..60f8aeda --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml_instruction.html @@ -0,0 +1,4 @@ + +

    Targets

    + +

    Inside: last

    diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml_instruction.json b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml_instruction.json new file mode 100644 index 00000000..f6ebfe0e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml_instruction.json @@ -0,0 +1,2 @@ +["html", "\u000a", ["p", "Targets ", " ", " "], + ["p", "Inside: ", " last"]] diff --git a/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml_instruction.text b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml_instruction.text new file mode 100644 index 00000000..7e42a418 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-maruku-unittest/xml_instruction.text @@ -0,0 +1,11 @@ + + + + + + +Targets + +Inside: last + + diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Abbr.html b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Abbr.html new file mode 100644 index 00000000..89d618d8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Abbr.html @@ -0,0 +1,11 @@ +

    Some text about HTML, SGML and HTML4.

    + +

    Let's talk about the U.S.A., (É.U. or É.-U. d'A. in French).

    + +

    And here we have a CD, some CDs, and some other CD's.

    + +

    Let's transfert documents through TCP/IP, using TCP packets.

    + +
    + +

    Bienvenue sur CMS.

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Abbr.json b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Abbr.json new file mode 100644 index 00000000..0470586f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Abbr.json @@ -0,0 +1,44 @@ +["html", ["p", "Some text about ", ["abbr", { + "title": "Hyper Text Markup Language" +}, +"HTML"], ", ", ["abbr", { + "title": "Standard Generalized Markup Language" +}, +"SGML"], " and ", ["abbr", { + "title": "Hyper Text Markup Language version 4" +}, +"HTML4"], "."], + ["p", "Let's talk about the ", ["abbr", { + "title": "United States of America" + }, + "U.S.A."], ", (", ["abbr", { + "title": "États-Unis d'Amérique" + }, + "É.U."], " or ", ["abbr", { + "title": "États-Unis d'Amérique" + }, + "É.-U. d'A."], " in French)."], + ["p", "And here we have a ", ["abbr", { + "title": "Compact Disk" + }, + "CD"], ", some CDs, and some other ", ["abbr", { + "title": "Compact Disk" + }, + "CD"], "'s."], + ["p", "Let's transfert documents through ", ["abbr", { + "title": "Transmission Control Protocol" + }, + "TCP"], "/", ["abbr", { + "title": "Internet Protocol" + }, + "IP"], ", using ", ["abbr", { + "title": "Transmission Control Protocol" + }, + "TCP"], " packets."], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", "Bienvenue sur ", ["a", { + "href": "http://www.bidulecms.com", + "title": "Bidule CMS" +}, +["abbr", { + "title": "Content Management System" +}, +"CMS"]], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Abbr.text b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Abbr.text new file mode 100644 index 00000000..5dd4ef2c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Abbr.text @@ -0,0 +1,25 @@ +Some text about HTML, SGML and HTML4. + +Let's talk about the U.S.A., (É.U. or É.-U. d'A. in French). + +*[HTML4]: Hyper Text Markup Language version 4 +*[HTML]: Hyper Text Markup Language +*[SGML]: Standard Generalized Markup Language +*[U.S.A.]: United States of America +*[É.U.] : États-Unis d'Amérique +*[É.-U. d'A.] : États-Unis d'Amérique + +And here we have a CD, some CDs, and some other CD's. + +*[CD]: Compact Disk + +Let's transfert documents through TCP/IP, using TCP packets. + +*[IP]: Internet Protocol +*[TCP]: Transmission Control Protocol + + --- + +Bienvenue sur [CMS](http://www.bidulecms.com "Bidule CMS"). + +*[CMS]: Content Management System \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Definition_Lists.html b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Definition_Lists.html new file mode 100644 index 00000000..0ab9f405 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Definition_Lists.html @@ -0,0 +1,142 @@ +

    A simple definition list:

    + +
    +
    Term 1
    +
    Definition 1
    + +
    Term 2
    +
    Definition 2
    +
    + +

    With multiple terms:

    + +
    +
    Term 1
    +
    Term 2
    +
    Definition 1
    + +
    Term 3
    +
    Term 4
    +
    Definition 2
    +
    + +

    With multiple definitions:

    + +
    +
    Term 1
    +
    Definition 1
    + +
    Definition 2
    + +
    Term 2
    +
    Definition 3
    + +
    Definition 4
    +
    + +

    With multiple lines per definition:

    + +
    +
    Term 1
    +
    Definition 1 line 1 ... +Definition 1 line 2
    + +
    Definition 2 line 1 ... +Definition 2 line 2
    + +
    Term 2
    +
    Definition 3 line 2 ... +Definition 3 line 2
    + +
    Definition 4 line 2 ... +Definition 4 line 2
    +
    + +

    With paragraphs:

    + +
    +
    Term 1
    +
    +

    Definition 1 (paragraph)

    +
    + +
    Term 2
    +
    +

    Definition 2 (paragraph)

    +
    +
    + +

    With multiple paragraphs:

    + +
    +
    Term 1
    +
    +

    Definition 1 paragraph 1 line 1 ... +Definition 1 paragraph 1 line 2

    + +

    Definition 1 paragraph 2 line 1 ... +Definition 1 paragraph 2 line 2

    +
    + +
    Term 2
    +
    +

    Definition 1 paragraph 1 line 1 ... +Definition 1 paragraph 1 line 2 (lazy)

    + +

    Definition 1 paragraph 2 line 1 ... +Definition 1 paragraph 2 line 2 (lazy)

    +
    +
    + +
    + +

    A mix:

    + +
    +
    Term 1
    +
    Term 2
    +
    +

    Definition 1 paragraph 1 line 1 ... +Definition 1 paragraph 1 line 2 (lazy)

    + +

    Definition 1 paragraph 2 line 1 ... +Definition 1 paragraph 2 line 2

    +
    + +
    +

    Definition 2 paragraph 1 line 1 ... +Definition 2 paragraph 1 line 2 (lazy)

    +
    + +
    Term 3
    +
    Definition 3 (no paragraph)
    + +
    Definition 4 (no paragraph)
    + +
    Definition 5 line 1 ... +Definition 5 line 2 (no paragraph)
    + +
    +

    Definition 6 paragraph 1 line 1 ... +Definition 6 paragraph 1 line 2

    +
    + +
    Definition 7 (no paragraph)
    + +
    +

    Definition 8 paragraph 1 line 1 (forced paragraph) ... +Definition 8 paragraph 1 line 2

    + +

    Definition 8 paragraph 2 line 1

    +
    + +
    Term 4
    +
    +

    Definition 9 paragraph 1 line 1 (forced paragraph) ... +Definition 9 paragraph 1 line 2

    + +

    Definition 9 paragraph 2 line 1

    +
    + +
    Definition 10 (no paragraph)
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Definition_Lists.json b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Definition_Lists.json new file mode 100644 index 00000000..b098d0da --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Definition_Lists.json @@ -0,0 +1,43 @@ +["html", ["p", "A simple definition list:"], "\u000a\u000a", ["dl", ["dt", "Term 1"], + ["dd", "Definition 1"], + ["dt", "Term 2"], + ["dd", "Definition 2"]], "\u000a\u000a", ["p", "With multiple terms:"], "\u000a\u000a", ["dl", ["dt", "Term 1"], + ["dt", "Term 2"], + ["dd", "Definition 1"], + ["dt", "Term 3"], + ["dt", "Term 4"], + ["dd", "Definition 2"]], "\u000a\u000a", ["p", "With multiple definitions:"], "\u000a\u000a", ["dl", ["dt", "Term 1"], + ["dd", "Definition 1"], + ["dd", "Definition 2"], + ["dt", "Term 2"], + ["dd", "Definition 3"], + ["dd", "Definition 4"]], "\u000a\u000a", ["p", "With multiple lines per definition:"], "\u000a\u000a", ["dl", ["dt", "Term 1"], + ["dd", "Definition 1 line 1 ...\u000aDefinition 1 line 2"], + ["dd", "Definition 2 line 1 ...\u000aDefinition 2 line 2"], + ["dt", "Term 2"], + ["dd", "Definition 3 line 2 ...\u000aDefinition 3 line 2"], + ["dd", "Definition 4 line 2 ...\u000aDefinition 4 line 2"]], "\u000a\u000a", ["p", "With paragraphs:"], "\u000a\u000a", ["dl", ["dt", "Term 1"], + ["dd", ["p", "Definition 1 (paragraph)"]], + ["dt", "Term 2"], + ["dd", ["p", "Definition 2 (paragraph)"]]], "\u000a\u000a", ["p", "With multiple paragraphs:"], "\u000a\u000a", ["dl", ["dt", "Term 1"], + ["dd", ["p", "Definition 1 paragraph 1 line 1 ...\u000aDefinition 1 paragraph 1 line 2"], + ["p", "Definition 1 paragraph 2 line 1 ...\u000aDefinition 1 paragraph 2 line 2"]], + ["dt", "Term 2"], + ["dd", ["p", "Definition 1 paragraph 1 line 1 ...\u000aDefinition 1 paragraph 1 line 2 (lazy)"], + ["p", "Definition 1 paragraph 2 line 1 ...\u000aDefinition 1 paragraph 2 line 2 (lazy)"]]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", "A mix:"], "\u000a\u000a", ["dl", ["dt", "Term 1"], + ["dt", "Term 2"], + ["dd", ["p", "Definition 1 paragraph 1 line 1 ...\u000aDefinition 1 paragraph 1 line 2 (lazy)"], + ["p", "Definition 1 paragraph 2 line 1 ...\u000aDefinition 1 paragraph 2 line 2"]], + ["dd", ["p", "Definition 2 paragraph 1 line 1 ...\u000aDefinition 2 paragraph 1 line 2 (lazy)"]], + ["dt", "Term 3"], + ["dd", "Definition 3 (no paragraph)"], + ["dd", "Definition 4 (no paragraph)"], + ["dd", "Definition 5 line 1 ...\u000aDefinition 5 line 2 (no paragraph)"], + ["dd", ["p", "Definition 6 paragraph 1 line 1 ...\u000aDefinition 6 paragraph 1 line 2"]], + ["dd", "Definition 7 (no paragraph)"], + ["dd", ["p", "Definition 8 paragraph 1 line 1 (forced paragraph) ...\u000aDefinition 8 paragraph 1 line 2"], + ["p", "Definition 8 paragraph 2 line 1"]], + ["dt", "Term 4"], + ["dd", ["p", "Definition 9 paragraph 1 line 1 (forced paragraph) ...\u000aDefinition 9 paragraph 1 line 2"], + ["p", "Definition 9 paragraph 2 line 1"]], + ["dd", "Definition 10 (no paragraph)"]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Definition_Lists.text b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Definition_Lists.text new file mode 100644 index 00000000..eae1fb5a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Definition_Lists.text @@ -0,0 +1,106 @@ +A simple definition list: + +Term 1 +: Definition 1 + +Term 2 +: Definition 2 + +With multiple terms: + +Term 1 +Term 2 +: Definition 1 + +Term 3 +Term 4 +: Definition 2 + +With multiple definitions: + +Term 1 +: Definition 1 +: Definition 2 + +Term 2 +: Definition 3 +: Definition 4 + +With multiple lines per definition: + +Term 1 +: Definition 1 line 1 ... +Definition 1 line 2 +: Definition 2 line 1 ... +Definition 2 line 2 + +Term 2 +: Definition 3 line 2 ... + Definition 3 line 2 +: Definition 4 line 2 ... + Definition 4 line 2 + +With paragraphs: + +Term 1 + +: Definition 1 (paragraph) + +Term 2 + +: Definition 2 (paragraph) + +With multiple paragraphs: + +Term 1 + +: Definition 1 paragraph 1 line 1 ... + Definition 1 paragraph 1 line 2 + + Definition 1 paragraph 2 line 1 ... + Definition 1 paragraph 2 line 2 + +Term 2 + +: Definition 1 paragraph 1 line 1 ... +Definition 1 paragraph 1 line 2 (lazy) + + Definition 1 paragraph 2 line 1 ... +Definition 1 paragraph 2 line 2 (lazy) + +* * * + +A mix: + +Term 1 +Term 2 + +: Definition 1 paragraph 1 line 1 ... +Definition 1 paragraph 1 line 2 (lazy) + + Definition 1 paragraph 2 line 1 ... + Definition 1 paragraph 2 line 2 + +: Definition 2 paragraph 1 line 1 ... +Definition 2 paragraph 1 line 2 (lazy) + +Term 3 +: Definition 3 (no paragraph) +: Definition 4 (no paragraph) +: Definition 5 line 1 ... + Definition 5 line 2 (no paragraph) + +: Definition 6 paragraph 1 line 1 ... +Definition 6 paragraph 1 line 2 +: Definition 7 (no paragraph) +: Definition 8 paragraph 1 line 1 (forced paragraph) ... + Definition 8 paragraph 1 line 2 + + Definition 8 paragraph 2 line 1 + +Term 4 +: Definition 9 paragraph 1 line 1 (forced paragraph) ... + Definition 9 paragraph 1 line 2 + + Definition 9 paragraph 2 line 1 +: Definition 10 (no paragraph) \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Emphasis.html b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Emphasis.html new file mode 100644 index 00000000..dfb11a74 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Emphasis.html @@ -0,0 +1,72 @@ +

    Combined emphasis:

    + +
      +
    1. test test
    2. +
    3. test test
    4. +
    5. test test
    6. +
    7. test test
    8. +
    9. test test
    10. +
    11. test test
    12. +
    13. test test
    14. +
    15. test test
    16. +
    17. test test
    18. +
    19. test test
    20. +
    21. test test
    22. +
    23. test test
    24. +
    25. test test
    26. +
    27. test test
    28. +
    29. test test
    30. +
    31. test test
    32. +
    + +

    Incorrect nesting:

    + +
      +
    1. *test test* test
    2. +
    3. _test test_ test
    4. +
    5. **test test* test*
    6. +
    7. __test test_ test_
    8. +
    9. test *test test*
    10. +
    11. test _test test_
    12. +
    13. test test test
    14. +
    15. test test test
    16. +
    + +

    No emphasis:

    + +
      +
    1. test* test *test
    2. +
    3. test** test **test
    4. +
    5. test_ test _test
    6. +
    7. test__ test __test
    8. +
    + +

    Middle-word emphasis (asterisks):

    + +
      +
    1. ab
    2. +
    3. ab
    4. +
    5. abc
    6. +
    7. ab
    8. +
    9. ab
    10. +
    11. abc
    12. +
    + +

    Middle-word emphasis (underscore):

    + +
      +
    1. _a_b
    2. +
    3. a_b_
    4. +
    5. a_b_c
    6. +
    7. __a__b
    8. +
    9. a__b__
    10. +
    11. a__b__c
    12. +
    + +

    my_precious_file.txt

    + +

    Tricky Cases

    + +

    E**. Test TestTestTest

    + +

    E**. Test Test Test Test

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Emphasis.json b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Emphasis.json new file mode 100644 index 00000000..10df510b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Emphasis.json @@ -0,0 +1,47 @@ +["html", ["p", "Combined emphasis:"], + ["ol", ["li", ["strong", ["em", "test test"]]], + ["li", ["strong", ["em", "test test"]]], + ["li", ["em", "test ", ["strong", "test"]]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["em", ["strong", "test"], " test"]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["em", "test ", ["strong", "test"]]], + ["li", ["em", "test ", ["strong", "test"]]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["em", ["strong", "test"], " test"]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["em", "test ", ["strong", "test"]]]], + ["p", "Incorrect nesting:"], + ["ol", ["li", "*test ", ["strong", "test* test"]], + ["li", "_test ", ["strong", "test_ test"]], + ["li", "**test ", ["em", "test"], "* test*"], + ["li", "__test ", ["em", "test"], "_ test_"], + ["li", ["em", "test *test"], " test*"], + ["li", ["em", "test _test"], " test_"], + ["li", ["strong", "test ", ["strong", "test"], " test"]], + ["li", ["strong", "test ", ["strong", "test"], " test"]]], + ["p", "No emphasis:"], + ["ol", ["li", "test* test *test"], + ["li", "test** test **test"], + ["li", "test_ test _test"], + ["li", "test__ test __test"]], + ["p", "Middle-word emphasis (asterisks):"], + ["ol", ["li", ["em", "a"], "b"], + ["li", "a", ["em", "b"]], + ["li", "a", ["em", "b"], "c"], + ["li", ["strong", "a"], "b"], + ["li", "a", ["strong", "b"]], + ["li", "a", ["strong", "b"], "c"]], + ["p", "Middle-word emphasis (underscore):"], + ["ol", ["li", "_a_b"], + ["li", "a_b_"], + ["li", "a_b_c"], + ["li", "__a__b"], + ["li", "a__b__"], + ["li", "a__b__c"]], + ["p", "my_precious_file.txt"], "\u000a\u000a", ["h2", "Tricky Cases"], "\u000a\u000a", ["p", "E**. ", ["strong", "Test"], " TestTestTest"], + ["p", "E**. ", ["strong", "Test"], " Test Test Test"]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Emphasis.text b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Emphasis.text new file mode 100644 index 00000000..ec48dec0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Emphasis.text @@ -0,0 +1,69 @@ +Combined emphasis: + +1. ***test test*** +2. ___test test___ +3. *test **test*** +4. **test *test*** +5. ***test* test** +6. ***test** test* +7. ***test* test** +8. **test *test*** +9. *test **test*** +10. _test __test___ +11. __test _test___ +12. ___test_ test__ +13. ___test__ test_ +14. ___test_ test__ +15. __test _test___ +16. _test __test___ + + +Incorrect nesting: + +1. *test **test* test** +2. _test __test_ test__ +3. **test *test** test* +4. __test _test__ test_ +5. *test *test* test* +6. _test _test_ test_ +7. **test **test** test** +8. __test __test__ test__ + + + +No emphasis: + +1. test* test *test +2. test** test **test +3. test_ test _test +4. test__ test __test + + + +Middle-word emphasis (asterisks): + +1. *a*b +2. a*b* +3. a*b*c +4. **a**b +5. a**b** +6. a**b**c + + +Middle-word emphasis (underscore): + +1. _a_b +2. a_b_ +3. a_b_c +4. __a__b +5. a__b__ +6. a__b__c + +my_precious_file.txt + + +## Tricky Cases + +E**. **Test** TestTestTest + +E**. **Test** Test Test Test diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Footnotes.html b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Footnotes.html new file mode 100644 index 00000000..d689588f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Footnotes.html @@ -0,0 +1,83 @@ +

    This is the first paragraph.1

    + +
      +
    • List item one.2
    • +
    • List item two.3
    • +
    + +

    Header4

    + +

    Some paragraph with a footnote5, and another6.

    + +

    Another paragraph with a named footnote7.

    + +

    This paragraph should not have a footnote marker since +the footnote is undefined.[^3]

    + +

    This paragraph should not have a footnote marker since +the footnote has already been used before.[^1]

    + +

    This paragraph links to a footnote with plenty of +block-level content.8

    + +

    This paragraph host the footnote reference within a +footnote test9.

    + +
    +
    +
      + +
    1. +

      This is the first note. 

      +
    2. + +
    3. +

      This is the second note. 

      +
    4. + +
    5. +

      This is the third note, defined out of order. 

      +
    6. + +
    7. +

      This is the fourth note. 

      +
    8. + +
    9. +

      Content for fifth footnote. 

      +
    10. + +
    11. +

      Content for sixth footnote spaning on +three lines, with some span-level markup like +emphasis, a link

      +
    12. + +
    13. +

      Footnote beginning on the line next to the marker. 

      +
    14. + +
    15. +

      Paragraph.

      + +
        +
      • List item
      • +
      + +
      +

      Blockquote

      +
      + +
      Code block
      +
      + +

      +
    16. + +
    17. +

      This footnote attemps to refer to another footnote. This +should be impossible.[^impossible] 

      +
    18. + +
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Footnotes.json b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Footnotes.json new file mode 100644 index 00000000..5938c558 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Footnotes.json @@ -0,0 +1,152 @@ +["html", ["p", "This is the first paragraph.", ["sup", { + "id": "fnref:first" +}, +["a", { + "href": "#fn:first", + "rel": "footnote" +}, +"1"]]], + ["ul", ["li", "List item one.", ["sup", { + "id": "fnref:second" + }, + ["a", { + "href": "#fn:second", + "rel": "footnote" + }, + "2"]]], + ["li", "List item two.", ["sup", { + "id": "fnref:third" + }, + ["a", { + "href": "#fn:third", + "rel": "footnote" + }, + "3"]]]], "\u000a\u000a", ["h1", "Header", ["sup", { + "id": "fnref:fourth" +}, +["a", { + "href": "#fn:fourth", + "rel": "footnote" +}, +"4"]]], "\u000a\u000a", ["p", "Some paragraph with a footnote", ["sup", { + "id": "fnref:1" +}, +["a", { + "href": "#fn:1", + "rel": "footnote" +}, +"5"]], ", and another", ["sup", { + "id": "fnref:2" +}, +["a", { + "href": "#fn:2", + "rel": "footnote" +}, +"6"]], "."], + ["p", "Another paragraph with a named footnote", ["sup", { + "id": "fnref:fn-name" + }, + ["a", { + "href": "#fn:fn-name", + "rel": "footnote" + }, + "7"]], "."], + ["p", "This paragraph should not have a footnote marker since \u000athe footnote is undefined.[^3]"], + ["p", "This paragraph should not have a footnote marker since \u000athe footnote has already been used before.[^1]"], + ["p", "This paragraph links to a footnote with plenty of \u000ablock-level content.", ["sup", { + "id": "fnref:block" + }, + ["a", { + "href": "#fn:block", + "rel": "footnote" + }, + "8"]]], + ["p", "This paragraph host the footnote reference within a \u000afootnote test", ["sup", { + "id": "fnref:reference" + }, + ["a", { + "href": "#fn:reference", + "rel": "footnote" + }, + "9"]], "."], "\u000a\u000a", ["div", { + "class": "footnotes" +}, +"\u000a", ["hr"], "\u000a", ["ol", ["li", { + "id": "fn:first" +}, +["p", "This is the first note. ", ["a", { + "href": "#fnref:first", + "rev": "footnote" +}, +"↩"]]], + ["li", { + "id": "fn:second" + }, + ["p", "This is the second note. ", ["a", { + "href": "#fnref:second", + "rev": "footnote" + }, + "↩"]]], + ["li", { + "id": "fn:third" + }, + ["p", "This is the third note, defined out of order. ", ["a", { + "href": "#fnref:third", + "rev": "footnote" + }, + "↩"]]], + ["li", { + "id": "fn:fourth" + }, + ["p", "This is the fourth note. ", ["a", { + "href": "#fnref:fourth", + "rev": "footnote" + }, + "↩"]]], + ["li", { + "id": "fn:1" + }, + ["p", "Content for fifth footnote. ", ["a", { + "href": "#fnref:1", + "rev": "footnote" + }, + "↩"]]], + ["li", { + "id": "fn:2" + }, + ["p", "Content for sixth footnote spaning on \u000athree lines, with some span-level markup like\u000a", ["em", "emphasis"], ", a ", ["a", { + "href": "http://www.michelf.com/" + }, + "link"], ". ", ["a", { + "href": "#fnref:2", + "rev": "footnote" + }, + "↩"]]], + ["li", { + "id": "fn:fn-name" + }, + ["p", "Footnote beginning on the line next to the marker. ", ["a", { + "href": "#fnref:fn-name", + "rev": "footnote" + }, + "↩"]]], + ["li", { + "id": "fn:block" + }, + ["p", "Paragraph."], + ["ul", ["li", "List item"]], + ["blockquote", ["p", "Blockquote"]], + ["pre", ["code", "Code block\u000a"]], + ["p", ["a", { + "href": "#fnref:block", + "rev": "footnote" + }, + "↩"]]], + ["li", { + "id": "fn:reference" + }, + ["p", "This footnote attemps to refer to another footnote. This \u000ashould be impossible.[^impossible] ", ["a", { + "href": "#fnref:reference", + "rev": "footnote" + }, + "↩"]]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Footnotes.text b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Footnotes.text new file mode 100644 index 00000000..d2cadf12 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Footnotes.text @@ -0,0 +1,55 @@ +This is the first paragraph.[^first] + +[^first]: This is the first note. + +* List item one.[^second] +* List item two.[^third] + +[^third]: This is the third note, defined out of order. +[^second]: This is the second note. +[^fourth]: This is the fourth note. + +# Header[^fourth] + +Some paragraph with a footnote[^1], and another[^2]. + +[^1]: Content for fifth footnote. +[^2]: Content for sixth footnote spaning on + three lines, with some span-level markup like + _emphasis_, a [link][]. + +[link]: http://www.michelf.com/ + +Another paragraph with a named footnote[^fn-name]. + +[^fn-name]: + Footnote beginning on the line next to the marker. + +This paragraph should not have a footnote marker since +the footnote is undefined.[^3] + +This paragraph should not have a footnote marker since +the footnote has already been used before.[^1] + +This paragraph links to a footnote with plenty of +block-level content.[^block] + +[^block]: + Paragraph. + + * List item + + > Blockquote + + Code block + +This paragraph host the footnote reference within a +footnote test[^reference]. + +[^reference]: + This footnote attemps to refer to another footnote. This + should be impossible.[^impossible] + +[^impossible]: + This footnote should not appear, as it is refered from + another footnote, which is not allowed. diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Inline_HTML_with_Markdown_content.html b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Inline_HTML_with_Markdown_content.html new file mode 100644 index 00000000..4751f786 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Inline_HTML_with_Markdown_content.html @@ -0,0 +1,125 @@ +

    Markdown inside code blocks

    + +
    + +

    foo

    + +
    + +
    + +

    foo

    + +
    + +
    + +

    foo

    + +
    + + + +
    test emphasis (span)
    + + + +
    test emphasis (span)
    + + + +
    + +

    test emphasis (block)

    + +
    + +

    More complicated

    + + + + + +
    +* this is not a list item
    +* this is not a list item
    + +
      +
    • this is a list item
    • +
    + +
    + +

    With indent

    + +
    +
    + +

    This text is no code block: if it was, the +closing <div> would be too and the HTML block +would be invalid.

    + +

    Markdown content in HTML blocks is assumed to be +indented the same as the block opening tag.

    + +

    This should be the third paragraph after the header.

    + +
    +
    + +

    Code block with rogue </div>s in Markdown code span and block

    + +
    +
    + +

    This is a code block however:

    + +
    </div>
    +
    + +

    Funny isn't it? Here is a code span: </div>.

    + +
    +
    + +
    +
    + +
      +
    • List item, not a code block
    • +
    + +

    Some text

    + +
    This is a code block.
    +
    + +
    +
    + +

    No code block in markdown span mode

    + +

    + This is not a code block since Markdown parse paragraph + content as span. Code spans like </p> are allowed though. +

    + +

    Hello world

    + +

    Preserving attributes and tags on more than one line:

    + +

    +Some span content. +

    + +

    Header confusion bug

    + + + + + +
    Hello World! +============ + +Hello World!
    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Inline_HTML_with_Markdown_content.json b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Inline_HTML_with_Markdown_content.json new file mode 100644 index 00000000..cd1f2a4e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Inline_HTML_with_Markdown_content.json @@ -0,0 +1,20 @@ +["html", ["h1", "Markdown inside code blocks"], "\u000a\u000a", ["div", ["p", "foo"]], "\u000a\u000a", ["div", ["p", "foo"]], "\u000a\u000a", ["div", ["p", "foo"]], "\u000a\u000a", ["table", ["tr", ["td", "test ", ["em", "emphasis"], " (span)"]]], "\u000a\u000a", ["table", ["tr", ["td", "test ", ["em", "emphasis"], " (span)"]]], "\u000a\u000a", ["table", ["tr", ["td", ["p", "test ", ["em", "emphasis"], " (block)"]]]], "\u000a\u000a", ["h2", "More complicated"], "\u000a\u000a", ["table", ["tr", ["td", "\u000a* this is ", ["em", "not"], " a list item"]], + ["tr", ["td", "\u000a* this is ", ["em", "not"], " a list item"]], + ["tr", ["td", ["ul", ["li", "this ", ["em", "is"], " a list item"]]]]], "\u000a\u000a", ["h2", "With indent"], "\u000a\u000a", ["div", "\u000a ", ["div", ["p", "This text is no code block: if it was, the \u000aclosing ", ["code", "
    "], " would be too and the HTML block \u000awould be invalid."], + ["p", "Markdown content in HTML blocks is assumed to be \u000aindented the same as the block opening tag."], + ["p", ["strong", "This should be the third paragraph after the header."]]], "\u000a"], "\u000a\u000a", ["h2", "Code block with rogue ", ["code", "
    "], "s in Markdown code span and block"], "\u000a\u000a", ["div", "\u000a ", ["div", ["p", "This is a code block however:"], + ["pre", ["code", "
    \u000a"]], + ["p", "Funny isn't it? Here is a code span: ", ["code", "
    "], "."]], "\u000a"], "\u000a\u000a", ["div", "\u000a ", ["div", ["ul", ["li", "List item, not a code block"]], + ["p", "Some text"], + ["pre", ["code", "This is a code block.\u000a"]]], "\u000a"], "\u000a\u000a", ["h2", "No code block in markdown span mode"], "\u000a\u000a", ["p", "\u000a This is not a code block since Markdown parse paragraph \u000a content as span. Code spans like ", ["code", "

    "], " are allowed though.\u000a"], + ["p", ["em", "Hello"], " ", ["em", "world"]], "\u000a\u000a", ["h2", "Preserving attributes and tags on more than one line:"], "\u000a\u000a", ["p", { + "class": "test", + "id": "12" +}, +"\u000aSome ", ["em", "span"], " content.\u000a"], "\u000a\u000a", ["h2", "Header confusion bug"], "\u000a\u000a", ["table", { + "class": "canvas" +}, +["tr", ["td", { + "id": "main" +}, +"Hello World!\u000a============\u000a\u000aHello World!"]]]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Inline_HTML_with_Markdown_content.text b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Inline_HTML_with_Markdown_content.text new file mode 100644 index 00000000..1eb54502 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Inline_HTML_with_Markdown_content.text @@ -0,0 +1,104 @@ +# Markdown inside code blocks + +
    +foo +
    + +
    +foo +
    + +
    +foo +
    + + + +
    test _emphasis_ (span)
    + + + +
    test _emphasis_ (span)
    + + + +
    test _emphasis_ (block)
    + +## More complicated + + + + + +
    +* this is _not_ a list item
    +* this is _not_ a list item
    +* this _is_ a list item +
    + +## With indent + +
    +
    + This text is no code block: if it was, the + closing `
    ` would be too and the HTML block + would be invalid. + + Markdown content in HTML blocks is assumed to be + indented the same as the block opening tag. + + **This should be the third paragraph after the header.** +
    +
    + +## Code block with rogue `
    `s in Markdown code span and block + +
    +
    + + This is a code block however: + +
    + + Funny isn't it? Here is a code span: `
    `. + +
    +
    + +
    +
    + * List item, not a code block + +Some text + + This is a code block. +
    +
    + +## No code block in markdown span mode + +

    + This is not a code block since Markdown parse paragraph + content as span. Code spans like `

    ` are allowed though. +

    + +

    _Hello_ _world_

    + +## Preserving attributes and tags on more than one line: + +

    +Some _span_ content. +

    + + +## Header confusion bug + + + + + +
    Hello World! +============ + +Hello World!
    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Tables.html b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Tables.html new file mode 100644 index 00000000..e36286c8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Tables.html @@ -0,0 +1,310 @@ +

    Simple tables

    + + + + + + + + + + + + + + + + + + +
    Header 1Header 2
    Cell 1Cell 2
    Cell 3Cell 4
    + +

    With leading pipes:

    + + + + + + + + + + + + + + + + + + +
    Header 1Header 2
    Cell 1Cell 2
    Cell 3Cell 4
    + +

    With tailing pipes:

    + + + + + + + + + + + + + + + + + + +
    Header 1Header 2
    Cell 1Cell 2
    Cell 3Cell 4
    + +

    With leading and tailing pipes:

    + + + + + + + + + + + + + + + + + + +
    Header 1Header 2
    Cell 1Cell 2
    Cell 3Cell 4
    + +
    + +

    One-column one-row table

    + +

    With leading pipes:

    + + + + + + + + + + + + +
    Header
    Cell
    + +

    With tailing pipes:

    + + + + + + + + + + + + +
    Header
    Cell
    + +

    With leading and tailing pipes:

    + + + + + + + + + + + + +
    Header
    Cell
    + +
    + +

    Table alignement:

    + + + + + + + + + + + + + + + + + + + + + + + + +
    DefaultRightCenterLeft
    Long CellLong CellLong CellLong Cell
    CellCellCellCell
    + +

    Table alignement (alternate spacing):

    + + + + + + + + + + + + + + + + + + + + + + + + +
    DefaultRightCenterLeft
    Long CellLong CellLong CellLong Cell
    CellCellCellCell
    + +
    + +

    Empty cells

    + + + + + + + + + + + + + + + + + + +
    Header 1Header 2
    AB
    C
    + + + + + + + + + + + + + + + + + + +
    Header 1Header 2
    AB
    D
    + +
    + +

    Missing tailing pipe

    + + + + + + + + + + + + + + + + + + +
    Header 1Header 2
    CellCell
    CellCell
    + + + + + + + + + + + + + + + + + + +
    Header 1Header 2
    CellCell
    CellCell
    + + + + + + + + + + + + + + + + + + +
    Header 1Header 2
    CellCell
    CellCell
    + + + + + + + + + + + + + + + + + + +
    Header 1Header 2
    CellCell
    CellCell
    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Tables.json b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Tables.json new file mode 100644 index 00000000..e25c9603 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Tables.json @@ -0,0 +1,130 @@ +["html", ["h1", "Simple tables"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header 1"], + ["th", "Header 2"]]], + ["tbody", ["tr", ["td", "Cell 1"], + ["td", "Cell 2"]], + ["tr", ["td", "Cell 3"], + ["td", "Cell 4"]]]], "\u000a\u000a", ["p", "With leading pipes:"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header 1"], + ["th", "Header 2"]]], + ["tbody", ["tr", ["td", "Cell 1"], + ["td", "Cell 2"]], + ["tr", ["td", "Cell 3"], + ["td", "Cell 4"]]]], "\u000a\u000a", ["p", "With tailing pipes:"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header 1"], + ["th", "Header 2"]]], + ["tbody", ["tr", ["td", "Cell 1"], + ["td", "Cell 2"]], + ["tr", ["td", "Cell 3"], + ["td", "Cell 4"]]]], "\u000a\u000a", ["p", "With leading and tailing pipes:"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header 1"], + ["th", "Header 2"]]], + ["tbody", ["tr", ["td", "Cell 1"], + ["td", "Cell 2"]], + ["tr", ["td", "Cell 3"], + ["td", "Cell 4"]]]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["h1", "One-column one-row table"], "\u000a\u000a", ["p", "With leading pipes:"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header"]]], + ["tbody", ["tr", ["td", "Cell"]]]], "\u000a\u000a", ["p", "With tailing pipes:"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header"]]], + ["tbody", ["tr", ["td", "Cell"]]]], "\u000a\u000a", ["p", "With leading and tailing pipes:"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header"]]], + ["tbody", ["tr", ["td", "Cell"]]]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", "Table alignement:"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Default"], + ["th", { + "align": "left" + }, + "Right"], + ["th", { + "align": "center" + }, + "Center"], + ["th", { + "align": "right" + }, + "Left"]]], + ["tbody", ["tr", ["td", "Long Cell"], + ["td", { + "align": "left" + }, + "Long Cell"], + ["td", { + "align": "center" + }, + "Long Cell"], + ["td", { + "align": "right" + }, + "Long Cell"]], + ["tr", ["td", "Cell"], + ["td", { + "align": "left" + }, + "Cell"], + ["td", { + "align": "center" + }, + "Cell"], + ["td", { + "align": "right" + }, + "Cell"]]]], "\u000a\u000a", ["p", "Table alignement (alternate spacing):"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Default"], + ["th", { + "align": "left" + }, + "Right"], + ["th", { + "align": "center" + }, + "Center"], + ["th", { + "align": "right" + }, + "Left"]]], + ["tbody", ["tr", ["td", "Long Cell"], + ["td", { + "align": "left" + }, + "Long Cell"], + ["td", { + "align": "center" + }, + "Long Cell"], + ["td", { + "align": "right" + }, + "Long Cell"]], + ["tr", ["td", "Cell"], + ["td", { + "align": "left" + }, + "Cell"], + ["td", { + "align": "center" + }, + "Cell"], + ["td", { + "align": "right" + }, + "Cell"]]]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["h1", "Empty cells"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header 1"], + ["th", "Header 2"]]], + ["tbody", ["tr", ["td", "A"], + ["td", "B"]], + ["tr", ["td", "C"], + ["td"]]]], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header 1"], + ["th", "Header 2"]]], + ["tbody", ["tr", ["td", "A"], + ["td", "B"]], + ["tr", ["td"], + ["td", "D"]]]], "\u000a\u000a", ["hr"], "\u000a\u000a", ["h1", "Missing tailing pipe"], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header 1"], + ["th", "Header 2"]]], + ["tbody", ["tr", ["td", "Cell"], + ["td", "Cell"]], + ["tr", ["td", "Cell"], + ["td", "Cell"]]]], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header 1"], + ["th", "Header 2"]]], + ["tbody", ["tr", ["td", "Cell"], + ["td", "Cell"]], + ["tr", ["td", "Cell"], + ["td", "Cell"]]]], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header 1"], + ["th", "Header 2"]]], + ["tbody", ["tr", ["td", "Cell"], + ["td", "Cell"]], + ["tr", ["td", "Cell"], + ["td", "Cell"]]]], "\u000a\u000a", ["table", ["thead", ["tr", ["th", "Header 1"], + ["th", "Header 2"]]], + ["tbody", ["tr", ["td", "Cell"], + ["td", "Cell"]], + ["tr", ["td", "Cell"], + ["td", "Cell"]]]]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Tables.text b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Tables.text new file mode 100644 index 00000000..71b93ca6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-extra/Tables.text @@ -0,0 +1,104 @@ +# Simple tables + +Header 1 | Header 2 +--------- | --------- +Cell 1 | Cell 2 +Cell 3 | Cell 4 + +With leading pipes: + +| Header 1 | Header 2 +| --------- | --------- +| Cell 1 | Cell 2 +| Cell 3 | Cell 4 + +With tailing pipes: + +Header 1 | Header 2 | +--------- | --------- | +Cell 1 | Cell 2 | +Cell 3 | Cell 4 | + +With leading and tailing pipes: + +| Header 1 | Header 2 | +| --------- | --------- | +| Cell 1 | Cell 2 | +| Cell 3 | Cell 4 | + +* * * + +# One-column one-row table + +With leading pipes: + +| Header +| ------- +| Cell + +With tailing pipes: + +Header | +------- | +Cell | + +With leading and tailing pipes: + +| Header | +| ------- | +| Cell | + +* * * + +Table alignement: + +| Default | Right | Center | Left | +| --------- |:--------- |:---------:| ---------:| +| Long Cell | Long Cell | Long Cell | Long Cell | +| Cell | Cell | Cell | Cell | + +Table alignement (alternate spacing): + +| Default | Right | Center | Left | +| --------- | :-------- | :-------: | --------: | +| Long Cell | Long Cell | Long Cell | Long Cell | +| Cell | Cell | Cell | Cell | + +* * * + +# Empty cells + +| Header 1 | Header 2 | +| --------- | --------- | +| A | B | +| C | | + +Header 1 | Header 2 +--------- | --------- +A | B + | D + +* * * + +# Missing tailing pipe + +Header 1 | Header 2 +--------- | --------- | +Cell | Cell | +Cell | Cell | + +Header 1 | Header 2 | +--------- | --------- +Cell | Cell | +Cell | Cell | + +Header 1 | Header 2 | +--------- | --------- | +Cell | Cell +Cell | Cell | + +Header 1 | Header 2 | +--------- | --------- | +Cell | Cell | +Cell | Cell + diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Email_auto_links.html b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Email_auto_links.html new file mode 100644 index 00000000..a32c4087 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Email_auto_links.html @@ -0,0 +1,3 @@ +

    michel.fortin@michelf.com

    + +

    International domain names: help@tūdaliņ.lv

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Email_auto_links.json b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Email_auto_links.json new file mode 100644 index 00000000..935fb6d9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Email_auto_links.json @@ -0,0 +1,8 @@ +["html", ["p", ["a", { + "href": "mailto:michel.fortin@michelf.com" +}, +"michel.fortin@michelf.com"]], + ["p", "International domain names: ", ["a", { + "href": "mailto:help@tūdaliņ.lv" + }, + "help@tūdaliņ.lv"]]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Email_auto_links.text b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Email_auto_links.text new file mode 100644 index 00000000..a8af4ec3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Email_auto_links.text @@ -0,0 +1,3 @@ + + +International domain names: \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Emphasis.html b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Emphasis.html new file mode 100644 index 00000000..73991324 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Emphasis.html @@ -0,0 +1,72 @@ +

    Combined emphasis:

    + +
      +
    1. test test
    2. +
    3. test test
    4. +
    5. test test
    6. +
    7. test test
    8. +
    9. test test
    10. +
    11. test test
    12. +
    13. test test
    14. +
    15. test test
    16. +
    17. test test
    18. +
    19. test test
    20. +
    21. test test
    22. +
    23. test test
    24. +
    25. test test
    26. +
    27. test test
    28. +
    29. test test
    30. +
    31. test test
    32. +
    + +

    Incorrect nesting:

    + +
      +
    1. *test test* test
    2. +
    3. _test test_ test
    4. +
    5. **test test* test*
    6. +
    7. __test test_ test_
    8. +
    9. test *test test*
    10. +
    11. test _test test_
    12. +
    13. test test test
    14. +
    15. test test test
    16. +
    + +

    No emphasis:

    + +
      +
    1. test* test *test
    2. +
    3. test** test **test
    4. +
    5. test_ test _test
    6. +
    7. test__ test __test
    8. +
    + +

    Middle-word emphasis (asterisks):

    + +
      +
    1. ab
    2. +
    3. ab
    4. +
    5. abc
    6. +
    7. ab
    8. +
    9. ab
    10. +
    11. abc
    12. +
    + +

    Middle-word emphasis (underscore):

    + +
      +
    1. ab
    2. +
    3. ab
    4. +
    5. abc
    6. +
    7. ab
    8. +
    9. ab
    10. +
    11. abc
    12. +
    + +

    mypreciousfile.txt

    + +

    Tricky Cases

    + +

    E**. Test TestTestTest

    + +

    E**. Test Test Test Test

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Emphasis.json b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Emphasis.json new file mode 100644 index 00000000..bc25ffd9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Emphasis.json @@ -0,0 +1,47 @@ +["html", ["p", "Combined emphasis:"], + ["ol", ["li", ["strong", ["em", "test test"]]], + ["li", ["strong", ["em", "test test"]]], + ["li", ["em", "test ", ["strong", "test"]]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["em", ["strong", "test"], " test"]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["em", "test ", ["strong", "test"]]], + ["li", ["em", "test ", ["strong", "test"]]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["em", ["strong", "test"], " test"]], + ["li", ["strong", ["em", "test"], " test"]], + ["li", ["strong", "test ", ["em", "test"]]], + ["li", ["em", "test ", ["strong", "test"]]]], + ["p", "Incorrect nesting:"], + ["ol", ["li", "*test ", ["strong", "test* test"]], + ["li", "_test ", ["strong", "test_ test"]], + ["li", "**test ", ["em", "test"], "* test*"], + ["li", "__test ", ["em", "test"], "_ test_"], + ["li", ["em", "test *test"], " test*"], + ["li", ["em", "test _test"], " test_"], + ["li", ["strong", "test ", ["strong", "test"], " test"]], + ["li", ["strong", "test ", ["strong", "test"], " test"]]], + ["p", "No emphasis:"], + ["ol", ["li", "test* test *test"], + ["li", "test** test **test"], + ["li", "test_ test _test"], + ["li", "test__ test __test"]], + ["p", "Middle-word emphasis (asterisks):"], + ["ol", ["li", ["em", "a"], "b"], + ["li", "a", ["em", "b"]], + ["li", "a", ["em", "b"], "c"], + ["li", ["strong", "a"], "b"], + ["li", "a", ["strong", "b"]], + ["li", "a", ["strong", "b"], "c"]], + ["p", "Middle-word emphasis (underscore):"], + ["ol", ["li", ["em", "a"], "b"], + ["li", "a", ["em", "b"]], + ["li", "a", ["em", "b"], "c"], + ["li", ["strong", "a"], "b"], + ["li", "a", ["strong", "b"]], + ["li", "a", ["strong", "b"], "c"]], + ["p", "my", ["em", "precious"], "file.txt"], "\u000a\u000a", ["h2", "Tricky Cases"], "\u000a\u000a", ["p", "E**. ", ["strong", "Test"], " TestTestTest"], + ["p", "E**. ", ["strong", "Test"], " Test Test Test"]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Emphasis.text b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Emphasis.text new file mode 100644 index 00000000..ec48dec0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Emphasis.text @@ -0,0 +1,69 @@ +Combined emphasis: + +1. ***test test*** +2. ___test test___ +3. *test **test*** +4. **test *test*** +5. ***test* test** +6. ***test** test* +7. ***test* test** +8. **test *test*** +9. *test **test*** +10. _test __test___ +11. __test _test___ +12. ___test_ test__ +13. ___test__ test_ +14. ___test_ test__ +15. __test _test___ +16. _test __test___ + + +Incorrect nesting: + +1. *test **test* test** +2. _test __test_ test__ +3. **test *test** test* +4. __test _test__ test_ +5. *test *test* test* +6. _test _test_ test_ +7. **test **test** test** +8. __test __test__ test__ + + + +No emphasis: + +1. test* test *test +2. test** test **test +3. test_ test _test +4. test__ test __test + + + +Middle-word emphasis (asterisks): + +1. *a*b +2. a*b* +3. a*b*c +4. **a**b +5. a**b** +6. a**b**c + + +Middle-word emphasis (underscore): + +1. _a_b +2. a_b_ +3. a_b_c +4. __a__b +5. a__b__ +6. a__b__c + +my_precious_file.txt + + +## Tricky Cases + +E**. **Test** TestTestTest + +E**. **Test** Test Test Test diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Inline_HTML_(Span).html b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Inline_HTML_(Span).html new file mode 100644 index 00000000..4d18affe --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Inline_HTML_(Span).html @@ -0,0 +1,4 @@ +

    ACINACS

    + +

    SB +SB

    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Inline_HTML_(Span).json b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Inline_HTML_(Span).json new file mode 100644 index 00000000..77e2b96c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Inline_HTML_(Span).json @@ -0,0 +1,11 @@ +["html", ["p", ["abbr", { + "title": "` **Attribute Content Is Not A Code Span** `" +}, +"ACINACS"]], + ["p", ["abbr", { + "title": "`first backtick!" + }, + "SB"], " \u000a", ["abbr", { + "title": "`second backtick!" + }, + "SB"]]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Inline_HTML_(Span).text b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Inline_HTML_(Span).text new file mode 100644 index 00000000..19028bb3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Inline_HTML_(Span).text @@ -0,0 +1,4 @@ +ACINACS + +SB +SB \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Ins_and_del.json b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Ins_and_del.json new file mode 100644 index 00000000..f907dab1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Ins_and_del.json @@ -0,0 +1,3 @@ +["html", ["p", "Here is a block tag ins:"], "\u000a\u000a", ["ins", ["p", "Some text"]], "\u000a\u000a", ["p", ["ins", "And here it is inside a paragraph."]], + ["p", "And here it is ", ["ins", "in the middle of"], " a paragraph."], "\u000a\u000a", ["del", ["p", "Some text"]], "\u000a\u000a", ["p", ["del", "And here is ins as a paragraph."]], + ["p", "And here it is ", ["del", "in the middle of"], " a paragraph."]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Ins_and_del.text b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Ins_and_del.text new file mode 100644 index 00000000..2d54c660 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Ins_and_del.text @@ -0,0 +1,17 @@ +Here is a block tag ins: + + +

    Some text

    +
    + +And here it is inside a paragraph. + +And here it is in the middle of a paragraph. + + +

    Some text

    +
    + +And here is ins as a paragraph. + +And here it is in the middle of a paragraph. diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Ins_and_del.xhtml b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Ins_and_del.xhtml new file mode 100644 index 00000000..60e8c5ff --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Ins_and_del.xhtml @@ -0,0 +1,17 @@ +

    Here is a block tag ins:

    + + +

    Some text

    +
    + +

    And here it is inside a paragraph.

    + +

    And here it is in the middle of a paragraph.

    + + +

    Some text

    +
    + +

    And here is ins as a paragraph.

    + +

    And here it is in the middle of a paragraph.

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Links_inline_style.html b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Links_inline_style.html new file mode 100644 index 00000000..d3e4d111 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Links_inline_style.html @@ -0,0 +1 @@ +

    silly URL w/ angle brackets.

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Links_inline_style.json b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Links_inline_style.json new file mode 100644 index 00000000..f7faf552 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Links_inline_style.json @@ -0,0 +1,4 @@ +["html", ["p", ["a", { + "href": "?}]*+|&)" +}, +"silly URL w/ angle brackets"], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Links_inline_style.text b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Links_inline_style.text new file mode 100644 index 00000000..600a0442 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Links_inline_style.text @@ -0,0 +1 @@ +[silly URL w/ angle brackets](). diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Nesting.html b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Nesting.html new file mode 100644 index 00000000..37845d31 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Nesting.html @@ -0,0 +1,11 @@ +

    Valid nesting:

    + +

    Link

    + +

    Link

    + +

    Link

    + +

    Invalid nesting:

    + +

    [Link](url)

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Nesting.json b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Nesting.json new file mode 100644 index 00000000..7aab7f0e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Nesting.json @@ -0,0 +1,18 @@ +["html", ["p", "Valid nesting:"], + ["p", ["strong", ["a", { + "href": "url" + }, + "Link"]]], + ["p", ["a", { + "href": "url" + }, + ["strong", "Link"]]], + ["p", ["strong", ["a", { + "href": "url" + }, + ["strong", "Link"]]]], + ["p", "Invalid nesting:"], + ["p", ["a", { + "href": "url" + }, + "[Link](url)"]]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Nesting.text b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Nesting.text new file mode 100644 index 00000000..791538c0 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Nesting.text @@ -0,0 +1,11 @@ +Valid nesting: + +**[Link](url)** + +[**Link**](url) + +**[**Link**](url)** + +Invalid nesting: + +[[Link](url)](url) \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Parens_in_URL.html b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Parens_in_URL.html new file mode 100644 index 00000000..a81aa029 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Parens_in_URL.html @@ -0,0 +1,11 @@ +

    Inline link 1 with parens.

    + +

    Inline link 2 with parens.

    + +

    Inline link 3 with non-escaped parens.

    + +

    Inline link 4 with non-escaped parens.

    + +

    Reference link 1 with parens.

    + +

    Reference link 2 with parens.

    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Parens_in_URL.json b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Parens_in_URL.json new file mode 100644 index 00000000..207a072f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Parens_in_URL.json @@ -0,0 +1,30 @@ +["html", ["p", ["a", { + "href": "/url(test)", + "title": "title" +}, +"Inline link 1 with parens"], "."], + ["p", ["a", { + "href": "/url(test)", + "title": "title" + }, + "Inline link 2 with parens"], "."], + ["p", ["a", { + "href": "/url(test)", + "title": "title" + }, + "Inline link 3 with non-escaped parens"], "."], + ["p", ["a", { + "href": "/url(test)", + "title": "title" + }, + "Inline link 4 with non-escaped parens"], "."], + ["p", ["a", { + "href": "/url(test)", + "title": "title" + }, + "Reference link 1 with parens"], "."], + ["p", ["a", { + "href": "/url(test)", + "title": "title" + }, + "Reference link 2 with parens"], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Parens_in_URL.text b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Parens_in_URL.text new file mode 100644 index 00000000..bb7be4fb --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown-todo/Parens_in_URL.text @@ -0,0 +1,14 @@ +[Inline link 1 with parens](/url\(test\) "title"). + +[Inline link 2 with parens]( "title"). + +[Inline link 3 with non-escaped parens](/url(test) "title"). + +[Inline link 4 with non-escaped parens]( "title"). + +[Reference link 1 with parens][1]. + +[Reference link 2 with parens][2]. + + [1]: /url(test) "title" + [2]: "title" diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Backslash_escapes.html b/node_modules/markdown/test/fixtures/docs-php-markdown/Backslash_escapes.html new file mode 100644 index 00000000..c5dbcfc2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Backslash_escapes.html @@ -0,0 +1,9 @@ +

    Tricky combinaisons:

    + +

    backslash with \-- two dashes

    + +

    backslash with \> greater than

    + +

    \[test](not a link)

    + +

    \*no emphasis*

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Backslash_escapes.json b/node_modules/markdown/test/fixtures/docs-php-markdown/Backslash_escapes.json new file mode 100644 index 00000000..fe607646 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Backslash_escapes.json @@ -0,0 +1,5 @@ +["html", ["p", "Tricky combinaisons:"], + ["p", "backslash with \\-- two dashes"], + ["p", "backslash with \\> greater than"], + ["p", "\\[test](not a link)"], + ["p", "\\*no emphasis*"]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Backslash_escapes.text b/node_modules/markdown/test/fixtures/docs-php-markdown/Backslash_escapes.text new file mode 100644 index 00000000..a5e769b7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Backslash_escapes.text @@ -0,0 +1 @@ +Tricky combinaisons: backslash with \\-- two dashes backslash with \\> greater than \\\[test](not a link) \\\*no emphasis* \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Code_Spans.html b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_Spans.html new file mode 100644 index 00000000..9ed0df87 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_Spans.html @@ -0,0 +1,6 @@ +

    From <!-- to --> +on two lines.

    + +

    From <!-- +to --> +on three lines.

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Code_Spans.json b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_Spans.json new file mode 100644 index 00000000..0854d4ff --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_Spans.json @@ -0,0 +1,2 @@ +["html", ["p", "From ", ["code", ""], "\u000aon two lines."], + ["p", "From ", ["code", ""], "\u000aon three lines."]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Code_Spans.text b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_Spans.text new file mode 100644 index 00000000..43f2bcfd --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_Spans.text @@ -0,0 +1,6 @@ +From `` +on two lines. + +From `` +on three lines. diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Code_block_in_a_list_item.html b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_block_in_a_list_item.html new file mode 100644 index 00000000..8ac5d83e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_block_in_a_list_item.html @@ -0,0 +1,11 @@ +
      +
    • List Item:

      + +
      code block
      +
      +
      +with a blank line
      +
      + +

      within a list item.

    • +
    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Code_block_in_a_list_item.json b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_block_in_a_list_item.json new file mode 100644 index 00000000..2d1ddf39 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_block_in_a_list_item.json @@ -0,0 +1,3 @@ +["html", ["ul", ["li", ["p", "List Item:"], + ["pre", ["code", "code block\u000a\u000a\u000awith a blank line\u000a"]], + ["p", "within a list item."]]]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Code_block_in_a_list_item.text b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_block_in_a_list_item.text new file mode 100644 index 00000000..3fa24c31 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Code_block_in_a_list_item.text @@ -0,0 +1,8 @@ + +* List Item: + + code block + + with a blank line + + within a list item. \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Headers.html b/node_modules/markdown/test/fixtures/docs-php-markdown/Headers.html new file mode 100644 index 00000000..3adb4707 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Headers.html @@ -0,0 +1,39 @@ +

    Header

    + +

    Header

    + +

    Header

    + +
    + +

    Header

    + +

    Paragraph

    + +

    Header

    + +

    Paragraph

    + +

    Header

    + +

    Paragraph

    + +
    + +

    Paragraph

    + +

    Header

    + +

    Paragraph

    + +

    Paragraph

    + +

    Header

    + +

    Paragraph

    + +

    Paragraph

    + +

    Header

    + +

    Paragraph

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Headers.json b/node_modules/markdown/test/fixtures/docs-php-markdown/Headers.json new file mode 100644 index 00000000..bd094895 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Headers.json @@ -0,0 +1,3 @@ +["html", ["h1", "Header"], "\u000a\u000a", ["h2", "Header"], "\u000a\u000a", ["h3", "Header"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["h1", "Header"], "\u000a\u000a", ["p", "Paragraph"], "\u000a\u000a", ["h2", "Header"], "\u000a\u000a", ["p", "Paragraph"], "\u000a\u000a", ["h3", "Header"], "\u000a\u000a", ["p", "Paragraph"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["p", "Paragraph"], "\u000a\u000a", ["h1", "Header"], "\u000a\u000a", ["p", "Paragraph"], + ["p", "Paragraph"], "\u000a\u000a", ["h2", "Header"], "\u000a\u000a", ["p", "Paragraph"], + ["p", "Paragraph"], "\u000a\u000a", ["h3", "Header"], "\u000a\u000a", ["p", "Paragraph"]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Headers.text b/node_modules/markdown/test/fixtures/docs-php-markdown/Headers.text new file mode 100644 index 00000000..3a39174a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Headers.text @@ -0,0 +1,9 @@ +Header ====== Header ------ ### Header + + - - - + +Header ====== Paragraph Header ------ Paragraph ### Header Paragraph + + - - - + +Paragraph Header ====== Paragraph Paragraph Header ------ Paragraph Paragraph ### Header Paragraph \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Images_(Untitled).html b/node_modules/markdown/test/fixtures/docs-php-markdown/Images_(Untitled).html new file mode 100644 index 00000000..1b9bc046 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Images_(Untitled).html @@ -0,0 +1,5 @@ +

    alt text

    + +

    alt text

    + +

    alt text

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Images_(Untitled).json b/node_modules/markdown/test/fixtures/docs-php-markdown/Images_(Untitled).json new file mode 100644 index 00000000..a46b0744 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Images_(Untitled).json @@ -0,0 +1,12 @@ +["html", ["p", ["img", { + "src": "/url/", + "alt": "alt text" +}]], + ["p", ["img", { + "src": "/url/", + "alt": "alt text" + }]], + ["p", ["img", { + "src": "/url/", + "alt": "alt text" + }]]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Images_(Untitled).text b/node_modules/markdown/test/fixtures/docs-php-markdown/Images_(Untitled).text new file mode 100644 index 00000000..cb481ded --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Images_(Untitled).text @@ -0,0 +1,7 @@ +![alt text](/url/) + +![alt text]() + +![alt text][foo] + + [foo]: /url/ \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_(Simple).html b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_(Simple).html new file mode 100644 index 00000000..facfefba --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_(Simple).html @@ -0,0 +1,15 @@ +

    With some attributes:

    + +
    + foo +
    + +
    + foo +
    + +

    Hr's:

    + +
    \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_(Simple).json b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_(Simple).json new file mode 100644 index 00000000..0cdbfd67 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_(Simple).json @@ -0,0 +1,11 @@ +["html", ["p", "With some attributes:"], "\u000a\u000a", ["div", { + "id": "test" +}, +"\u000a foo\u000a"], "\u000a\u000a", ["div", { + "id": "test", + "class": "nono" +}, +"\u000a foo\u000a"], "\u000a\u000a", ["p", "Hr's:"], "\u000a\u000a", ["hr", { + "class": "foo", + "id": "bar" +}]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_(Simple).text b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_(Simple).text new file mode 100644 index 00000000..9177105e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_(Simple).text @@ -0,0 +1,15 @@ +With some attributes: + +
    + foo +
    + +
    + foo +
    + +Hr's: + +
    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_comments.html b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_comments.html new file mode 100644 index 00000000..b45f0148 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_comments.html @@ -0,0 +1,9 @@ +

    Paragraph one.

    + + + +

    Paragraph two.

    + + + +

    The end.

    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_comments.json b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_comments.json new file mode 100644 index 00000000..fd65c352 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_comments.json @@ -0,0 +1 @@ +["html", ["p", "Paragraph one."], "\u000a\u000a", "\u000a\u000a", ["p", "Paragraph two."], "\u000a\u000a", "\u000a\u000a", ["p", "The end."]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_comments.text b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_comments.text new file mode 100644 index 00000000..d57d00aa --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Inline_HTML_comments.text @@ -0,0 +1,9 @@ +Paragraph one. + + + +Paragraph two. + + + +The end. diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/PHP-Specific_Bugs.html b/node_modules/markdown/test/fixtures/docs-php-markdown/PHP-Specific_Bugs.html new file mode 100644 index 00000000..c982417b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/PHP-Specific_Bugs.html @@ -0,0 +1,17 @@ +

    This tests for a bug where quotes escaped by PHP when using +preg_replace with the /e modifier must be correctly unescaped +(hence the _UnslashQuotes function found only in PHP Markdown).

    + +

    Headers below should appear exactly as they are typed (no backslash +added or removed).

    + +

    Header "quoted\" again \""

    + +

    Header "quoted\" again \""

    + +

    Header "quoted\" again \""

    + +

    Test with tabs for _Detab:

    + +
    Code    'block' with    some    "tabs"  and "quotes"
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/PHP-Specific_Bugs.json b/node_modules/markdown/test/fixtures/docs-php-markdown/PHP-Specific_Bugs.json new file mode 100644 index 00000000..ce3dfae4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/PHP-Specific_Bugs.json @@ -0,0 +1,3 @@ +["html", ["p", "This tests for a bug where quotes escaped by PHP when using \u000a", ["code", "preg_replace"], " with the ", ["code", "/e"], " modifier must be correctly unescaped\u000a(hence the ", ["code", "_UnslashQuotes"], " function found only in PHP Markdown)."], + ["p", "Headers below should appear exactly as they are typed (no backslash\u000aadded or removed)."], "\u000a\u000a", ["h1", "Header \"quoted\\\" again \\\"\""], "\u000a\u000a", ["h2", "Header \"quoted\\\" again \\\"\""], "\u000a\u000a", ["h3", "Header \"quoted\\\" again \\\"\""], "\u000a\u000a", ["p", "Test with tabs for ", ["code", "_Detab"], ":"], + ["pre", ["code", "Code 'block' with some \"tabs\" and \"quotes\"\u000a"]]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/PHP-Specific_Bugs.text b/node_modules/markdown/test/fixtures/docs-php-markdown/PHP-Specific_Bugs.text new file mode 100644 index 00000000..246b60d1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/PHP-Specific_Bugs.text @@ -0,0 +1,22 @@ +This tests for a bug where quotes escaped by PHP when using +`preg_replace` with the `/e` modifier must be correctly unescaped +(hence the `_UnslashQuotes` function found only in PHP Markdown). + + + +Headers below should appear exactly as they are typed (no backslash +added or removed). + +Header "quoted\" again \\"" +=========================== + +Header "quoted\" again \\"" +--------------------------- + +### Header "quoted\" again \\"" ### + + + +Test with tabs for `_Detab`: + + Code 'block' with some "tabs" and "quotes" diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Tight_blocks.html b/node_modules/markdown/test/fixtures/docs-php-markdown/Tight_blocks.html new file mode 100644 index 00000000..86554308 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Tight_blocks.html @@ -0,0 +1,21 @@ +

    Paragraph and no space: +* ciao

    + +

    Paragraph and 1 space: + * ciao

    + +

    Paragraph and 3 spaces: + * ciao

    + +

    Paragraph and 4 spaces: + * ciao

    + +

    Paragraph before header:

    + +

    Header

    + +

    Paragraph before blockquote:

    + +
    +

    Some quote.

    +
    diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Tight_blocks.json b/node_modules/markdown/test/fixtures/docs-php-markdown/Tight_blocks.json new file mode 100644 index 00000000..116b198b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Tight_blocks.json @@ -0,0 +1,6 @@ +["html", ["p", "Paragraph and no space:\u000a* ciao"], + ["p", "Paragraph and 1 space:\u000a * ciao"], + ["p", "Paragraph and 3 spaces:\u000a * ciao"], + ["p", "Paragraph and 4 spaces:\u000a * ciao"], + ["p", "Paragraph before header:"], "\u000a\u000a", ["h1", "Header"], "\u000a\u000a", ["p", "Paragraph before blockquote:"], + ["blockquote", ["p", "Some quote."]]] diff --git a/node_modules/markdown/test/fixtures/docs-php-markdown/Tight_blocks.text b/node_modules/markdown/test/fixtures/docs-php-markdown/Tight_blocks.text new file mode 100644 index 00000000..ae4cdcb4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-php-markdown/Tight_blocks.text @@ -0,0 +1 @@ +Paragraph and no space: * ciao Paragraph and 1 space: * ciao Paragraph and 3 spaces: * ciao Paragraph and 4 spaces: * ciao Paragraph before header: #Header Paragraph before blockquote: >Some quote. \ No newline at end of file diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link.html new file mode 100644 index 00000000..e4dde058 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link.html @@ -0,0 +1,3 @@ +

    I can has autolink? http://icanhascheeseburger.com

    + +

    Ask garfield: garfield@example.com

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link.json new file mode 100644 index 00000000..3748db61 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link.json @@ -0,0 +1,8 @@ +["html", ["p", "I can has autolink? ", ["a", { + "href": "http://icanhascheeseburger.com" +}, +"http://icanhascheeseburger.com"]], + ["p", "Ask garfield: ", ["a", { + "href": "mailto:garfield@example.com" + }, + "garfield@example.com"]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link.text new file mode 100644 index 00000000..e5354cd4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link.text @@ -0,0 +1,3 @@ +I can has autolink? + +Ask garfield: diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.html new file mode 100644 index 00000000..e4dde058 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.html @@ -0,0 +1,3 @@ +

    I can has autolink? http://icanhascheeseburger.com

    + +

    Ask garfield: garfield@example.com

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.json new file mode 100644 index 00000000..3748db61 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.json @@ -0,0 +1,8 @@ +["html", ["p", "I can has autolink? ", ["a", { + "href": "http://icanhascheeseburger.com" +}, +"http://icanhascheeseburger.com"]], + ["p", "Ask garfield: ", ["a", { + "href": "mailto:garfield@example.com" + }, + "garfield@example.com"]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.opts new file mode 100644 index 00000000..ccb6a09b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.opts @@ -0,0 +1 @@ +{'safe_mode': True} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.text new file mode 100644 index 00000000..e5354cd4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/auto_link_safe_mode.text @@ -0,0 +1,3 @@ +I can has autolink? + +Ask garfield: diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.html new file mode 100644 index 00000000..393e9d2c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.html @@ -0,0 +1,5 @@ +

    blah [HTML_REMOVED] blah

    + +

    [HTML_REMOVED]yowzer![HTML_REMOVED]

    + +

    blah

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.json new file mode 100644 index 00000000..4d6a31f4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.json @@ -0,0 +1,3 @@ +["html", ["p", "blah [HTML_REMOVED] blah"], + ["p", "[HTML_REMOVED]yowzer![HTML_REMOVED]"], + ["p", "blah"]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.opts new file mode 100644 index 00000000..e74c7cce --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.opts @@ -0,0 +1,2 @@ +# Use the old (for-compat-only) way of specifying "replace" safe mode. +{"safe_mode": True} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.text new file mode 100644 index 00000000..ee042312 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode.text @@ -0,0 +1,5 @@ +blah blah + +
    yowzer!
    + +blah diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.html new file mode 100644 index 00000000..af24510c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.html @@ -0,0 +1,5 @@ +

    blah <img src="dangerous"> blah

    + +

    <div>yowzer!</div>

    + +

    blah

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.json new file mode 100644 index 00000000..02c9efb5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.json @@ -0,0 +1,3 @@ +["html", ["p", "blah blah"], + ["p", "
    yowzer!
    "], + ["p", "blah"]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.opts new file mode 100644 index 00000000..ad487c04 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.opts @@ -0,0 +1 @@ +{"safe_mode": "escape"} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.text new file mode 100644 index 00000000..ee042312 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/basic_safe_mode_escape.text @@ -0,0 +1,5 @@ +blah blah + +
    yowzer!
    + +blah diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote.html new file mode 100644 index 00000000..5cde1cba --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote.html @@ -0,0 +1,11 @@ +

    [Trent wrote]

    + +
    +

    no way

    +
    + +

    [Jeff wrote]

    + +
    +

    way

    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote.json new file mode 100644 index 00000000..bb208127 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote.json @@ -0,0 +1,4 @@ +["html", ["p", "[Trent wrote]"], + ["blockquote", ["p", "no way"]], + ["p", "[Jeff wrote]"], + ["blockquote", ["p", "way"]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote.text new file mode 100644 index 00000000..3bcecaa3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote.text @@ -0,0 +1,5 @@ +[Trent wrote] +> no way + +[Jeff wrote] +> way diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote_with_pre.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote_with_pre.html new file mode 100644 index 00000000..d03cc785 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote_with_pre.html @@ -0,0 +1,9 @@ +
    +

    Markdown indents blockquotes a couple of spaces + necessitating some tweaks for pre-blocks in that + blockquote:

    + +
    here is a check
    +for that
    +
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote_with_pre.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote_with_pre.json new file mode 100644 index 00000000..acd4c3d2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote_with_pre.json @@ -0,0 +1,2 @@ +["html", ["blockquote", ["p", "Markdown indents blockquotes a couple of spaces\u000a necessitating some tweaks for pre-blocks in that\u000a blockquote:"], + ["pre", ["code", "here is a check\u000afor that\u000a"]]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote_with_pre.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote_with_pre.text new file mode 100644 index 00000000..e61b82f7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/blockquote_with_pre.text @@ -0,0 +1,6 @@ +> Markdown indents blockquotes a couple of spaces +> necessitating some tweaks for pre-blocks in that +> blockquote: +> +> here is a check +> for that diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_block_with_tabs.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_block_with_tabs.html new file mode 100644 index 00000000..6c32e465 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_block_with_tabs.html @@ -0,0 +1,4 @@ +

    Test with tabs for _Detab:

    + +
    Code    'block' with    some    "tabs"  and "quotes"
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_block_with_tabs.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_block_with_tabs.json new file mode 100644 index 00000000..735e24d8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_block_with_tabs.json @@ -0,0 +1,2 @@ +["html", ["p", "Test with tabs for ", ["code", "_Detab"], ":"], + ["pre", ["code", "Code 'block' with some \"tabs\" and \"quotes\"\u000a"]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_block_with_tabs.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_block_with_tabs.text new file mode 100644 index 00000000..bcf94c48 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_block_with_tabs.text @@ -0,0 +1,3 @@ +Test with tabs for `_Detab`: + + Code 'block' with some "tabs" and "quotes" diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.html new file mode 100644 index 00000000..f53e6a5f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.html @@ -0,0 +1,2 @@ +

    This is italic and this is bold. +This is NOT _italic_ and this is __bold__ because --code-safe is turned on.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.json new file mode 100644 index 00000000..8799d6ff --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.json @@ -0,0 +1 @@ +["html", ["p", "This is ", ["em", "italic"], " and this is ", ["strong", "bold"], ".\u000aThis is NOT _italic_ and this is __bold__ because --code-safe is turned on."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.opts new file mode 100644 index 00000000..cd0b9d61 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.opts @@ -0,0 +1 @@ +{"extras": ["code-friendly"]} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.text new file mode 100644 index 00000000..c5474830 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/code_safe_emphasis.text @@ -0,0 +1,2 @@ +This is *italic* and this is **bold**. +This is NOT _italic_ and this is __bold__ because --code-safe is turned on. diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codeblock.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codeblock.html new file mode 100644 index 00000000..bf7f5c23 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codeblock.html @@ -0,0 +1,8 @@ +
    some code
    +
    + +

    some 'splaining

    + +
    some more code
    +2 > 1
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codeblock.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codeblock.json new file mode 100644 index 00000000..5a5bf5e2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codeblock.json @@ -0,0 +1,3 @@ +["html", ["pre", ["code", "some code\u000a"]], + ["p", "some 'splaining"], + ["pre", ["code", "some more code\u000a2 > 1\u000a"]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codeblock.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codeblock.text new file mode 100644 index 00000000..d374216f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codeblock.text @@ -0,0 +1,7 @@ + some code + +some 'splaining + + some more code + 2 > 1 + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans.html new file mode 100644 index 00000000..3528bcde --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans.html @@ -0,0 +1,2 @@ +

    This is a code span. +And This is one with an `embedded backtick`.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans.json new file mode 100644 index 00000000..9d3f44c4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans.json @@ -0,0 +1 @@ +["html", ["p", ["code", "This"], " is a code span.\u000aAnd ", ["code", "This is one with an `embedded backtick`"], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans.text new file mode 100644 index 00000000..67015a9f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans.text @@ -0,0 +1,2 @@ +`This` is a code span. +And ``This is one with an `embedded backtick` ``. diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.html new file mode 100644 index 00000000..3528bcde --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.html @@ -0,0 +1,2 @@ +

    This is a code span. +And This is one with an `embedded backtick`.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.json new file mode 100644 index 00000000..9d3f44c4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.json @@ -0,0 +1 @@ +["html", ["p", ["code", "This"], " is a code span.\u000aAnd ", ["code", "This is one with an `embedded backtick`"], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.opts new file mode 100644 index 00000000..ccb6a09b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.opts @@ -0,0 +1 @@ +{'safe_mode': True} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.text new file mode 100644 index 00000000..67015a9f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/codespans_safe_mode.text @@ -0,0 +1,2 @@ +`This` is a code span. +And ``This is one with an `embedded backtick` ``. diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_head_vars.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_head_vars.html new file mode 100644 index 00000000..b194eb9e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_head_vars.html @@ -0,0 +1,4 @@ + + +

    This sentence talks about the Python __init__ method, which I'd rather not be +interpreted as Markdown's strong.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_head_vars.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_head_vars.json new file mode 100644 index 00000000..bbec5ed5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_head_vars.json @@ -0,0 +1 @@ +["html", "\u000a\u000a", ["p", "This sentence talks about the Python __init__ method, which I'd rather not be\u000ainterpreted as Markdown's strong."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_head_vars.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_head_vars.text new file mode 100644 index 00000000..2d05ab8c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_head_vars.text @@ -0,0 +1,4 @@ + + +This sentence talks about the Python __init__ method, which I'd rather not be +interpreted as Markdown's strong. diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_tail_vars.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_tail_vars.html new file mode 100644 index 00000000..8b470115 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_tail_vars.html @@ -0,0 +1,8 @@ +

    This sentence talks about the Python __init__ method, which I'd rather not be +interpreted as Markdown's strong.

    + + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_tail_vars.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_tail_vars.json new file mode 100644 index 00000000..648993fd --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_tail_vars.json @@ -0,0 +1 @@ +["html", ["p", "This sentence talks about the Python __init__ method, which I'd rather not be\u000ainterpreted as Markdown's strong."], "\u000a\u000a", "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_tail_vars.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_tail_vars.text new file mode 100644 index 00000000..400d2eb9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emacs_tail_vars.text @@ -0,0 +1,8 @@ +This sentence talks about the Python __init__ method, which I'd rather not be +interpreted as Markdown's strong. + + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emphasis.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emphasis.html new file mode 100644 index 00000000..a850dc97 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emphasis.html @@ -0,0 +1,2 @@ +

    This is italic and this is bold. +This is also italic and this is bold.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emphasis.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emphasis.json new file mode 100644 index 00000000..705d1e8c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emphasis.json @@ -0,0 +1 @@ +["html", ["p", "This is ", ["em", "italic"], " and this is ", ["strong", "bold"], ".\u000aThis is also ", ["em", "italic"], " and this is ", ["strong", "bold"], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emphasis.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emphasis.text new file mode 100644 index 00000000..202dba6a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/emphasis.text @@ -0,0 +1,2 @@ +This is *italic* and this is **bold**. +This is also _italic_ and this is __bold__. diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/escapes.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/escapes.html new file mode 100644 index 00000000..9670548b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/escapes.html @@ -0,0 +1,3 @@ +

    **don't shout**

    + +

    *don't emphasize*

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/escapes.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/escapes.json new file mode 100644 index 00000000..a86965b3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/escapes.json @@ -0,0 +1,2 @@ +["html", ["p", "**don't shout**"], + ["p", "*don't emphasize*"]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/escapes.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/escapes.text new file mode 100644 index 00000000..a79164e3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/escapes.text @@ -0,0 +1,3 @@ +\*\*don't shout\*\* + +\*don't emphasize\* diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.html new file mode 100644 index 00000000..37c6d8b2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.html @@ -0,0 +1,27 @@ +

    This is a para with a footnote.1

    + +

    This is another para with a footnote2 in it. Actually it has two3 of +them. No, three4.

    + +
    +
    +
      +
    1. +

      Here is the body of the first footnote. 

      +
    2. + +
    3. +

      And of the second footnote.

      + +

      This one has multiple paragraphs. 

      +
    4. + +
    5. +

      Here is a footnote body that starts on next line. 

      +
    6. + +
    7. +

      quickie "that looks like a link ref if not careful" 

      +
    8. +
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.json new file mode 100644 index 00000000..8d26e3c3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.json @@ -0,0 +1,69 @@ +["html", ["p", "This is a para with a footnote.", ["sup", { + "class": "footnote-ref", + "id": "fnref-1" +}, +["a", { + "href": "#fn-1" +}, +"1"]]], + ["p", "This is another para with a footnote", ["sup", { + "class": "footnote-ref", + "id": "fnref-2" + }, + ["a", { + "href": "#fn-2" + }, + "2"]], " in it. Actually it has two", ["sup", { + "class": "footnote-ref", + "id": "fnref-3" + }, + ["a", { + "href": "#fn-3" + }, + "3"]], " of\u000athem. No, three", ["sup", { + "class": "footnote-ref", + "id": "fnref-4" + }, + ["a", { + "href": "#fn-4" + }, + "4"]], "."], "\u000a\u000a", ["div", { + "class": "footnotes" +}, +"\u000a", ["hr"], "\u000a", ["ol", ["li", { + "id": "fn-1" +}, +["p", "Here is the body of the first footnote.", ["a", { + "href": "#fnref-1", + "class": "footnoteBackLink", + "title": "Jump back to footnote 1 in the text." +}, +"↩"]]], + ["li", { + "id": "fn-2" + }, + ["p", "And of the second footnote."], + ["p", "This one has multiple paragraphs.", ["a", { + "href": "#fnref-2", + "class": "footnoteBackLink", + "title": "Jump back to footnote 2 in the text." + }, + "↩"]]], + ["li", { + "id": "fn-3" + }, + ["p", "Here is a footnote body that starts on next line.", ["a", { + "href": "#fnref-3", + "class": "footnoteBackLink", + "title": "Jump back to footnote 3 in the text." + }, + "↩"]]], + ["li", { + "id": "fn-4" + }, + ["p", "quickie \"that looks like a link ref if not careful\"", ["a", { + "href": "#fnref-4", + "class": "footnoteBackLink", + "title": "Jump back to footnote 4 in the text." + }, + "↩"]]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.opts new file mode 100644 index 00000000..9dfee9e2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.opts @@ -0,0 +1 @@ +{"extras": ["footnotes"]} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.text new file mode 100644 index 00000000..7d6e7163 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes.text @@ -0,0 +1,18 @@ +This is a para with a footnote.[^1] + +This is another para with a footnote[^2] in it. Actually it has two[^3] of +them. No, three[^4]. + + +[^1]: Here is the body of the first footnote. + +[^2]: And of the second footnote. + + This one has multiple paragraphs. + +[^3]: + Here is a footnote body that starts on next line. + +[^4]: quickie "that looks like a link ref if not careful" + + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.html new file mode 100644 index 00000000..3702606f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.html @@ -0,0 +1,23 @@ +

    This is a para with a footnote.1

    + +

    This is another para with a footnote2 in it. Actually it has two3 of +them.

    + +
    +
    +
      +
    1. +

      Here is the body of the first footnote. 

      +
    2. + +
    3. +

      And of the second footnote.

      + +

      This one has multiple paragraphs. 

      +
    4. + +
    5. +

      Here is a footnote body that starts on next line. 

      +
    6. +
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.json new file mode 100644 index 00000000..3452a4c1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.json @@ -0,0 +1,53 @@ +["html", ["p", "This is a para with a footnote.", ["sup", { + "class": "footnote-ref", + "id": "fnref-foo" +}, +["a", { + "href": "#fn-foo" +}, +"1"]]], + ["p", "This is another para with a footnote", ["sup", { + "class": "footnote-ref", + "id": "fnref-hyphen-ated" + }, + ["a", { + "href": "#fn-hyphen-ated" + }, + "2"]], " in it. Actually it has two", ["sup", { + "class": "footnote-ref", + "id": "fnref-Capital" + }, + ["a", { + "href": "#fn-Capital" + }, + "3"]], " of\u000athem."], "\u000a\u000a", ["div", { + "class": "footnotes" +}, +"\u000a", ["hr"], "\u000a", ["ol", ["li", { + "id": "fn-foo" +}, +["p", "Here is the body of the first footnote.", ["a", { + "href": "#fnref-foo", + "class": "footnoteBackLink", + "title": "Jump back to footnote 1 in the text." +}, +"↩"]]], + ["li", { + "id": "fn-hyphen-ated" + }, + ["p", "And of the second footnote."], + ["p", "This one has multiple paragraphs.", ["a", { + "href": "#fnref-hyphen-ated", + "class": "footnoteBackLink", + "title": "Jump back to footnote 2 in the text." + }, + "↩"]]], + ["li", { + "id": "fn-Capital" + }, + ["p", "Here is a footnote body that starts on next line.", ["a", { + "href": "#fnref-Capital", + "class": "footnoteBackLink", + "title": "Jump back to footnote 3 in the text." + }, + "↩"]]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.opts new file mode 100644 index 00000000..9dfee9e2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.opts @@ -0,0 +1 @@ +{"extras": ["footnotes"]} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.text new file mode 100644 index 00000000..431a96b3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_letters.text @@ -0,0 +1,15 @@ +This is a para with a footnote.[^foo] + +This is another para with a footnote[^hyphen-ated] in it. Actually it has two[^Capital] of +them. + + +[^foo]: Here is the body of the first footnote. + +[^hyphen-ated]: And of the second footnote. + + This one has multiple paragraphs. + +[^Capital]: + Here is a footnote body that starts on next line. + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.html new file mode 100644 index 00000000..f3650416 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.html @@ -0,0 +1,22 @@ +

    This is a para with a footnote.1

    + +

    This is another para with a footnote.2

    + +
    +
    +
      +
    1. +

      And the body of the footnote has markup. For example, +a link to digg. And some code:

      + +
      print "Hello, World!"
      +
      + +

      +
    2. + +
    3. +

      This body has markup too, but doesn't end with a code block. 

      +
    4. +
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.json new file mode 100644 index 00000000..c2c8676a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.json @@ -0,0 +1,41 @@ +["html", ["p", "This is a para with a footnote.", ["sup", { + "class": "footnote-ref", + "id": "fnref-1" +}, +["a", { + "href": "#fn-1" +}, +"1"]]], + ["p", "This is another para with a footnote.", ["sup", { + "class": "footnote-ref", + "id": "fnref-2" + }, + ["a", { + "href": "#fn-2" + }, + "2"]]], "\u000a\u000a", ["div", { + "class": "footnotes" +}, +"\u000a", ["hr"], "\u000a", ["ol", ["li", { + "id": "fn-1" +}, +["p", "And the ", ["strong", "body"], " of the footnote has ", ["code", "markup"], ". For example,\u000aa ", ["a", { + "href": "http://digg.com" +}, +"link to digg"], ". And some code:"], + ["pre", ["code", "print \"Hello, World!\"\u000a"]], + ["p", ["a", { + "href": "#fnref-1", + "class": "footnoteBackLink", + "title": "Jump back to footnote 1 in the text." + }, + "↩"]]], + ["li", { + "id": "fn-2" + }, + ["p", "This body has markup too, ", ["em", "but"], " doesn't end with a code block.", ["a", { + "href": "#fnref-2", + "class": "footnoteBackLink", + "title": "Jump back to footnote 2 in the text." + }, + "↩"]]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.opts new file mode 100644 index 00000000..9dfee9e2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.opts @@ -0,0 +1 @@ +{"extras": ["footnotes"]} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.text new file mode 100644 index 00000000..07b59223 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_markup.text @@ -0,0 +1,10 @@ +This is a para with a footnote.[^1] + +This is another para with a footnote.[^2] + +[^1]: And the **body** of the footnote has `markup`. For example, + a [link to digg](http://digg.com). And some code: + + print "Hello, World!" + +[^2]: This body has markup too, *but* doesn't end with a code block. diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.html new file mode 100644 index 00000000..6bce5a7b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.html @@ -0,0 +1,12 @@ +

    This is a para with a footnote.1

    + +
    +
    +
      +
    1. +

      Here is the <em>body</em> of <span class="yo">the</span> footnote.

      + +

      <div class="blah">And here is the second para of the footnote.</div> 

      +
    2. +
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.json new file mode 100644 index 00000000..9e00e0ee --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.json @@ -0,0 +1,20 @@ +["html", ["p", "This is a para with a footnote.", ["sup", { + "class": "footnote-ref", + "id": "fnref-1" +}, +["a", { + "href": "#fn-1" +}, +"1"]]], "\u000a\u000a", ["div", { + "class": "footnotes" +}, +"\u000a", ["hr"], "\u000a", ["ol", ["li", { + "id": "fn-1" +}, +["p", "Here is the body of the footnote."], + ["p", "
    And here is the second para of the footnote.
    ", ["a", { + "href": "#fnref-1", + "class": "footnoteBackLink", + "title": "Jump back to footnote 1 in the text." + }, + "↩"]]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.opts new file mode 100644 index 00000000..9d97404b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.opts @@ -0,0 +1 @@ +{"safe_mode": "escape", "extras": ["footnotes"]} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.text new file mode 100644 index 00000000..ae8e4e7d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/footnotes_safe_mode_escape.text @@ -0,0 +1,6 @@ +This is a para with a footnote.[^1] + +[^1]: Here is the body of the footnote. + +
    And here is the second para of the footnote.
    + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/header.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/header.html new file mode 100644 index 00000000..90fc68a8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/header.html @@ -0,0 +1,7 @@ +

    an h1

    + +

    an h2

    + +

    another h1

    + +

    another h2

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/header.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/header.json new file mode 100644 index 00000000..1300b250 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/header.json @@ -0,0 +1 @@ +["html", ["h1", "an h1"], "\u000a\u000a", ["h2", "an h2"], "\u000a\u000a", ["h1", "another h1"], "\u000a\u000a", ["h2", "another h2"], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/header.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/header.text new file mode 100644 index 00000000..5ab06fd1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/header.text @@ -0,0 +1,9 @@ +# an h1 + +## an h2 + +another h1 +========== + +another h2 +---------- diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/hr.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/hr.html new file mode 100644 index 00000000..442117ee --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/hr.html @@ -0,0 +1,12 @@ +

    Dashes:

    + +
    + +
    + +
    + +
    + +
    ---
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/hr.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/hr.json new file mode 100644 index 00000000..edea7caf --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/hr.json @@ -0,0 +1 @@ +["html", ["p", "Dashes:"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["hr"], "\u000a\u000a", ["pre", ["code", "---\u000a"]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/hr.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/hr.text new file mode 100644 index 00000000..765b735e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/hr.text @@ -0,0 +1,12 @@ +Dashes: + +--- + + --- + + --- + + --- + + --- + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/img_in_link.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/img_in_link.html new file mode 100644 index 00000000..09db27a7 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/img_in_link.html @@ -0,0 +1,4 @@ +

    This example from +http://orestis.gr/en/blog/2007/05/28/python-markdown-problems/:

    + +

    the google logo

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/img_in_link.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/img_in_link.json new file mode 100644 index 00000000..2662ec9a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/img_in_link.json @@ -0,0 +1,12 @@ +["html", ["p", "This example from\u000a", ["a", { + "href": "http://orestis.gr/en/blog/2007/05/28/python-markdown-problems/" +}, +"http://orestis.gr/en/blog/2007/05/28/python-markdown-problems/"], ":"], + ["p", ["a", { + "href": "http://www.google.com/", + "title": "click to visit Google.com" + }, + ["img", { + "src": "http://www.google.com/images/logo.gif", + "alt": "the google logo" + }]]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/img_in_link.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/img_in_link.text new file mode 100644 index 00000000..8a0c1fda --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/img_in_link.text @@ -0,0 +1,7 @@ +This example from +: + +[![the google logo][logo]][google] +[logo]: http://www.google.com/images/logo.gif +[google]: http://www.google.com/ "click to visit Google.com" + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/inline_links.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/inline_links.html new file mode 100644 index 00000000..ad2aa72d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/inline_links.html @@ -0,0 +1,7 @@ +

    an inline link

    + +

    a link "with" title

    + +

    an inline image link

    + +

    an image "with" title

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/inline_links.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/inline_links.json new file mode 100644 index 00000000..5dc43f19 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/inline_links.json @@ -0,0 +1,18 @@ +["html", ["p", "an inline ", ["a", { + "href": "/url/" +}, +"link"]], + ["p", "a ", ["a", { + "href": "/url/", + "title": "title" + }, + "link \"with\" title"]], + ["p", "an inline ", ["img", { + "src": "/url/", + "alt": "image link" + }]], + ["p", "an ", ["img", { + "src": "/url/", + "alt": "image \"with\" title", + "title": "title" + }]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/inline_links.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/inline_links.text new file mode 100644 index 00000000..444a9975 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/inline_links.text @@ -0,0 +1,7 @@ +an inline [link](/url/) + +a [link "with" title](/url/ "title") + +an inline ![image link](/url/) + +an ![image "with" title](/url/ "title") diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.html new file mode 100644 index 00000000..c36b6d9a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.html @@ -0,0 +1,5 @@ +

    Heading 2

    + +

    blah [HTML_REMOVED]alert('this should be removed')[HTML_REMOVED] blah

    + +

    [HTML_REMOVED]alert('as should this')[HTML_REMOVED]

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.json new file mode 100644 index 00000000..483d1c1a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.json @@ -0,0 +1,2 @@ +["html", ["h2", "Heading 2"], "\u000a\u000a", ["p", "blah [HTML_REMOVED]alert('this should be removed')[HTML_REMOVED] ", ["strong", "blah"]], + ["p", "[HTML_REMOVED]alert('as should this')[HTML_REMOVED]"]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.opts new file mode 100644 index 00000000..fd31b4e3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.opts @@ -0,0 +1 @@ +{"safe_mode": "replace"} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.text new file mode 100644 index 00000000..38cb2b5b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/issue2_safe_mode_borks_markup.text @@ -0,0 +1,6 @@ +## Heading 2 + +blah **blah** + + + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_defn_alt_title_delims.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_defn_alt_title_delims.html new file mode 100644 index 00000000..57871fb5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_defn_alt_title_delims.html @@ -0,0 +1,3 @@ +

    Alternative delimiters for link definitions are allowed -- as of +Markdown 1.0.2, I think. Hence, this link and this link work +too.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_defn_alt_title_delims.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_defn_alt_title_delims.json new file mode 100644 index 00000000..e35e754a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_defn_alt_title_delims.json @@ -0,0 +1,13 @@ +["html", ["p", "Alternative delimiters for ", ["a", { + "href": "http://daringfireball.net/projects/markdown/syntax#link", + "title": "link syntax" +}, +"link definitions"], " are allowed -- as of\u000aMarkdown 1.0.2, I think. Hence, ", ["a", { + "href": "http://daringfireball.net/projects/markdown/syntax#link", + "title": "link syntax" +}, +"this link"], " and ", ["a", { + "href": "http://daringfireball.net/projects/markdown/syntax#link", + "title": "link syntax" +}, +"this link"], " work\u000atoo."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_defn_alt_title_delims.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_defn_alt_title_delims.text new file mode 100644 index 00000000..3d62b11d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_defn_alt_title_delims.text @@ -0,0 +1,7 @@ +Alternative delimiters for [link definitions][link1] are allowed -- as of +Markdown 1.0.2, I think. Hence, [this link][link2] and [this link][link3] work +too. + +[link1]: http://daringfireball.net/projects/markdown/syntax#link "link syntax" +[link2]: http://daringfireball.net/projects/markdown/syntax#link 'link syntax' +[link3]: http://daringfireball.net/projects/markdown/syntax#link (link syntax) diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.html new file mode 100644 index 00000000..6c98ea97 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.html @@ -0,0 +1 @@ +

    Recipe 123 and Komodo bug 234 are related.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.json new file mode 100644 index 00000000..c7b0dcb4 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.json @@ -0,0 +1,7 @@ +["html", ["p", ["a", { + "href": "http://code.activestate.com/recipes/123/" +}, +"Recipe 123"], " and ", ["a", { + "href": "http://bugs.activestate.com/show_bug.cgi?id=234" +}, +"Komodo bug 234"], " are related."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.opts new file mode 100644 index 00000000..bd85ea91 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.opts @@ -0,0 +1,7 @@ +{"extras": ["link-patterns"], + "link_patterns": [ + (re.compile("recipe\s+(\d+)", re.I), r"http://code.activestate.com/recipes/\1/"), + (re.compile("(?:komodo\s+)?bug\s+(\d+)", re.I), r"http://bugs.activestate.com/show_bug.cgi?id=\1"), + ], +} + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.text new file mode 100644 index 00000000..d8a40813 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns.text @@ -0,0 +1 @@ +Recipe 123 and Komodo bug 234 are related. diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.html new file mode 100644 index 00000000..4402dcf6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.html @@ -0,0 +1 @@ +

    There once was a Mozilla bug 123 and a Komodo bug 123.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.json new file mode 100644 index 00000000..52163772 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.json @@ -0,0 +1,7 @@ +["html", ["p", "There once was a ", ["a", { + "href": "http://bugzilla.mozilla.org/show_bug.cgi?id=123" +}, +"Mozilla bug 123"], " and a ", ["a", { + "href": "http://bugs.activestate.com/show_bug.cgi?id=123" +}, +"Komodo bug 123"], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.opts new file mode 100644 index 00000000..d64982d8 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.opts @@ -0,0 +1,7 @@ +{"extras": ["link-patterns"], + "link_patterns": [ + (re.compile(r'mozilla\s+bug\s+(\d+)', re.I), r'http://bugzilla.mozilla.org/show_bug.cgi?id=\1'), + (re.compile("(?:komodo\s+)?bug\s+(\d+)", re.I), r"http://bugs.activestate.com/show_bug.cgi?id=\1"), + ], +} + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.text new file mode 100644 index 00000000..29868b8d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_double_hit.text @@ -0,0 +1 @@ +There once was a Mozilla bug 123 and a Komodo bug 123. diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.html new file mode 100644 index 00000000..ffd0a72e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.html @@ -0,0 +1 @@ +

    Blah 123 becomes a line with two underscores.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.json new file mode 100644 index 00000000..ad16ccfa --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.json @@ -0,0 +1,4 @@ +["html", ["p", ["a", { + "href": "http://foo.com/blah_blah_blah/123" +}, +"Blah 123"], " becomes a line with two underscores."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.opts new file mode 100644 index 00000000..99ce0f79 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.opts @@ -0,0 +1,6 @@ +{"extras": ["link-patterns"], + "link_patterns": [ + (re.compile("Blah\s+(\d+)", re.I), r"http://foo.com/blah_blah_blah/\1"), + ], +} + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.text new file mode 100644 index 00000000..d1fb62cf --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/link_patterns_edge_cases.text @@ -0,0 +1 @@ +Blah 123 becomes a line with two underscores. diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/lists.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/lists.html new file mode 100644 index 00000000..f34c900b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/lists.html @@ -0,0 +1,15 @@ +

    count:

    + +
      +
    • one
    • +
    • two
    • +
    • three
    • +
    + +

    count in spanish:

    + +
      +
    1. uno
    2. +
    3. dos
    4. +
    5. tres
    6. +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/lists.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/lists.json new file mode 100644 index 00000000..2c1c55dd --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/lists.json @@ -0,0 +1,8 @@ +["html", ["p", "count:"], + ["ul", ["li", "one"], + ["li", "two"], + ["li", "three"]], + ["p", "count in spanish:"], + ["ol", ["li", "uno"], + ["li", "dos"], + ["li", "tres"]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/lists.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/lists.text new file mode 100644 index 00000000..8d2b43c6 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/lists.text @@ -0,0 +1,11 @@ +count: + +* one +* two +* three + +count in spanish: + +1. uno +2. dos +3. tres diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.html new file mode 100644 index 00000000..7ac7bfd5 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.html @@ -0,0 +1,16 @@ +

    This is sentence has a footnote foo1 and whamo[^whamo].

    + +

    This is another para with a numbered footnote2.

    + +
    +
    +
      +
    1. +

      Here is the body of the footnote foo. 

      +
    2. + +
    3. +

      Here is the body of the footnote 6. 

      +
    4. +
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.json new file mode 100644 index 00000000..69e09d87 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.json @@ -0,0 +1,36 @@ +["html", ["p", "This is sentence has a footnote foo", ["sup", { + "class": "footnote-ref", + "id": "fnref-foo" +}, +["a", { + "href": "#fn-foo" +}, +"1"]], " and whamo[^whamo]."], + ["p", "This is another para with a numbered footnote", ["sup", { + "class": "footnote-ref", + "id": "fnref-6" + }, + ["a", { + "href": "#fn-6" + }, + "2"]], "."], "\u000a\u000a", ["div", { + "class": "footnotes" +}, +"\u000a", ["hr"], "\u000a", ["ol", ["li", { + "id": "fn-foo" +}, +["p", "Here is the body of the footnote foo.", ["a", { + "href": "#fnref-foo", + "class": "footnoteBackLink", + "title": "Jump back to footnote 1 in the text." +}, +"↩"]]], + ["li", { + "id": "fn-6" + }, + ["p", "Here is the body of the footnote 6.", ["a", { + "href": "#fnref-6", + "class": "footnoteBackLink", + "title": "Jump back to footnote 2 in the text." + }, + "↩"]]]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.opts new file mode 100644 index 00000000..9dfee9e2 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.opts @@ -0,0 +1 @@ +{"extras": ["footnotes"]} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.text new file mode 100644 index 00000000..d6791923 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/mismatched_footnotes.text @@ -0,0 +1,9 @@ +This is sentence has a footnote foo[^foo] and whamo[^whamo]. + +This is another para with a numbered footnote[^6]. + + +[^foo]: Here is the body of the footnote foo. +[^bar]: Here is the body of the footnote bar. +[^6]: Here is the body of the footnote 6. + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/missing_link_defn.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/missing_link_defn.html new file mode 100644 index 00000000..2f8a9e8a --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/missing_link_defn.html @@ -0,0 +1 @@ +

    This is a [missing link][missing] and a used link.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/missing_link_defn.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/missing_link_defn.json new file mode 100644 index 00000000..b2bc9d44 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/missing_link_defn.json @@ -0,0 +1,4 @@ +["html", ["p", "This is a [missing link][missing] and a ", ["a", { + "href": "http://foo.com" +}, +"used link"], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/missing_link_defn.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/missing_link_defn.text new file mode 100644 index 00000000..817677f9 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/missing_link_defn.text @@ -0,0 +1,7 @@ + +This is a [missing link][missing] and a [used link][used]. + + +[used]: http://foo.com +[unused]: http://foo.com + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list.html new file mode 100644 index 00000000..c0617e42 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list.html @@ -0,0 +1,15 @@ +

    shopping list:

    + +
      +
    • veggies +
        +
      • carrots
      • +
      • lettuce
      • +
    • +
    • fruits +
        +
      • oranges
      • +
      • apples
      • +
      • peaches
      • +
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list.json new file mode 100644 index 00000000..6879f11c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list.json @@ -0,0 +1,6 @@ +["html", ["p", "shopping list:"], + ["ul", ["li", "veggies\u000a", ["ul", ["li", "carrots"], + ["li", "lettuce"]]], + ["li", "fruits\u000a", ["ul", ["li", "oranges"], + ["li", "apples"], + ["li", ["em", "peaches"]]]]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list.text new file mode 100644 index 00000000..a37a1954 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list.text @@ -0,0 +1,9 @@ +shopping list: + +- veggies + + carrots + + lettuce +- fruits + + oranges + + apples + + *peaches* diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.html new file mode 100644 index 00000000..c0617e42 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.html @@ -0,0 +1,15 @@ +

    shopping list:

    + +
      +
    • veggies +
        +
      • carrots
      • +
      • lettuce
      • +
    • +
    • fruits +
        +
      • oranges
      • +
      • apples
      • +
      • peaches
      • +
    • +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.json new file mode 100644 index 00000000..6879f11c --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.json @@ -0,0 +1,6 @@ +["html", ["p", "shopping list:"], + ["ul", ["li", "veggies\u000a", ["ul", ["li", "carrots"], + ["li", "lettuce"]]], + ["li", "fruits\u000a", ["ul", ["li", "oranges"], + ["li", "apples"], + ["li", ["em", "peaches"]]]]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.opts new file mode 100644 index 00000000..ccb6a09b --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.opts @@ -0,0 +1 @@ +{'safe_mode': True} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.text new file mode 100644 index 00000000..a37a1954 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/nested_list_safe_mode.text @@ -0,0 +1,9 @@ +shopping list: + +- veggies + + carrots + + lettuce +- fruits + + oranges + + apples + + *peaches* diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/parens_in_url_4.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/parens_in_url_4.html new file mode 100644 index 00000000..6535e80d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/parens_in_url_4.html @@ -0,0 +1 @@ +

    Inline link 4 with non-escaped parens.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/parens_in_url_4.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/parens_in_url_4.json new file mode 100644 index 00000000..2d9e60bd --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/parens_in_url_4.json @@ -0,0 +1,5 @@ +["html", ["p", ["a", { + "href": "/url(test)", + "title": "title" +}, +"Inline link 4 with non-escaped parens"], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/parens_in_url_4.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/parens_in_url_4.text new file mode 100644 index 00000000..5dfb9ab3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/parens_in_url_4.text @@ -0,0 +1 @@ +[Inline link 4 with non-escaped parens]( "title"). diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/raw_html.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/raw_html.html new file mode 100644 index 00000000..ec135c6e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/raw_html.html @@ -0,0 +1,5 @@ +

    Hi, there. blah

    + +
    + **ack** +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/raw_html.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/raw_html.json new file mode 100644 index 00000000..ff401bbf --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/raw_html.json @@ -0,0 +1,4 @@ +["html", ["p", "Hi, ", ["span", { + "foo": "*bar*" +}, +["em", "there"]], ". ", " blah"], "\u000a\u000a", ["div", "\u000a **ack**\u000a"], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/raw_html.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/raw_html.text new file mode 100644 index 00000000..13cde378 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/raw_html.text @@ -0,0 +1,6 @@ + +Hi, *there*. blah + +
    + **ack** +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/ref_links.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/ref_links.html new file mode 100644 index 00000000..406f8b54 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/ref_links.html @@ -0,0 +1 @@ +

    Google is fast star.

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/ref_links.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/ref_links.json new file mode 100644 index 00000000..95493a80 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/ref_links.json @@ -0,0 +1,7 @@ +["html", ["p", ["a", { + "href": "http://www.google.com/" +}, +"Google"], " is fast ", ["img", { + "src": "/img/star.png", + "alt": "star" +}], "."]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/ref_links.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/ref_links.text new file mode 100644 index 00000000..4df8c01e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/ref_links.text @@ -0,0 +1,6 @@ +[Google][] is fast ![star][]. + +[google]: http://www.google.com/ +[star]: /img/star.png + + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/sublist-para.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/sublist-para.html new file mode 100644 index 00000000..a2f551b1 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/sublist-para.html @@ -0,0 +1,17 @@ +

    Some quick thoughts from a coder's perspective:

    + +
      +
    • The source will be available in a Mercurial ...

    • +
    • Komodo is a Mozilla-based application...

      + +
        +
      • Get a slightly tweaked mozilla build (C++, JavaScript, XUL).
      • +
      • Get a slightly tweaks Python build (C).
      • +
      • Add a bunch of core logic (Python)...
      • +
      • Add Komodo chrome (XUL, JavaScript, CSS, DTDs).
      • +
      + +

      What this means is that work on and add significant functionality...

    • +
    • Komodo uses the same extension mechanisms as Firefox...

    • +
    • Komodo builds and runs on Windows, Linux and ...

    • +

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/sublist-para.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/sublist-para.json new file mode 100644 index 00000000..24adae88 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/sublist-para.json @@ -0,0 +1,10 @@ +["html", ["p", "Some quick thoughts from a coder's perspective:"], + ["ul", ["li", ["p", "The source will be available in a Mercurial ..."]], + ["li", ["p", "Komodo is a Mozilla-based application..."], + ["ul", ["li", "Get a slightly tweaked mozilla build (C++, JavaScript, XUL)."], + ["li", "Get a slightly tweaks Python build (C)."], + ["li", "Add a bunch of core logic (Python)..."], + ["li", "Add Komodo chrome (XUL, JavaScript, CSS, DTDs)."]], + ["p", ["p", "What this means is that work on and add significant functionality..."]]], + ["li", ["p", "Komodo uses the same extension mechanisms as Firefox..."]], + ["li", ["p", "Komodo builds and runs on Windows, Linux and ..."]]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/sublist-para.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/sublist-para.text new file mode 100644 index 00000000..7bf07ba3 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/sublist-para.text @@ -0,0 +1,17 @@ +Some quick thoughts from a coder's perspective: + +- The source will be available in a Mercurial ... + +- Komodo is a Mozilla-based application... + + - Get a slightly tweaked mozilla build (C++, JavaScript, XUL). + - Get a slightly tweaks Python build (C). + - Add a bunch of core logic (Python)... + - Add Komodo chrome (XUL, JavaScript, CSS, DTDs). + + What this means is that work on and add significant functionality... + +- Komodo uses the same extension mechanisms as Firefox... + +- Komodo builds and runs on Windows, Linux and ... + diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.html new file mode 100644 index 00000000..2e172c13 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.html @@ -0,0 +1,15 @@ +

    Here is some sample code:

    + +
    import sys
    +def main(argv=sys.argv):
    +    logging.basicConfig()
    +    log.info('hi')
    +
    + +

    and:

    + +
    use 'zlib'
    +sub main(argv)
    +    puts 'hi'
    +end
    +
    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.json new file mode 100644 index 00000000..9c1f198e --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.json @@ -0,0 +1,118 @@ +["html", ["p", "Here is some sample code:"], "\u000a\u000a", ["div", { + "class": "codehilite" +}, +["pre", ["code", ["span", { + "class": "k" +}, +"import"], " ", ["span", { + "class": "nn" +}, +"sys"], "\u000a", ["span", { + "class": "k" +}, +"def"], " ", ["span", { + "class": "nf" +}, +"main"], + ["span", { + "class": "p" + }, + "("], + ["span", { + "class": "n" + }, + "argv"], + ["span", { + "class": "o" + }, + "="], + ["span", { + "class": "n" + }, + "sys"], + ["span", { + "class": "o" + }, + "."], + ["span", { + "class": "n" + }, + "argv"], + ["span", { + "class": "p" + }, + "):"], "\u000a ", ["span", { + "class": "n" +}, +"logging"], + ["span", { + "class": "o" + }, + "."], + ["span", { + "class": "n" + }, + "basicConfig"], + ["span", { + "class": "p" + }, + "()"], "\u000a ", ["span", { + "class": "n" +}, +"log"], + ["span", { + "class": "o" + }, + "."], + ["span", { + "class": "n" + }, + "info"], + ["span", { + "class": "p" + }, + "("], + ["span", { + "class": "s" + }, + "'hi'"], + ["span", { + "class": "p" + }, + ")"], "\u000a"]]], "\u000a\u000a", ["p", "and:"], "\u000a\u000a", ["div", { + "class": "codehilite" +}, +["pre", ["code", ["span", { + "class": "n" +}, +"use"], " ", ["span", { + "class": "s1" +}, +"'zlib'"], "\u000a", ["span", { + "class": "nb" +}, +"sub"], " ", ["span", { + "class": "n" +}, +"main"], + ["span", { + "class": "p" + }, + "("], + ["span", { + "class": "n" + }, + "argv"], + ["span", { + "class": "p" + }, + ")"], "\u000a ", ["span", { + "class": "nb" +}, +"puts"], " ", ["span", { + "class": "s1" +}, +"'hi'"], "\u000a", ["span", { + "class": "k" +}, +"end"], "\u000a"]]], "\u000a"] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.opts b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.opts new file mode 100644 index 00000000..95dfd418 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.opts @@ -0,0 +1 @@ +{"extras": ["code-color"]} diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.text new file mode 100644 index 00000000..b4b30e55 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/syntax_color.text @@ -0,0 +1,15 @@ +Here is some sample code: + + :::python + import sys + def main(argv=sys.argv): + logging.basicConfig() + log.info('hi') + +and: + + :::ruby + use 'zlib' + sub main(argv) + puts 'hi' + end diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/tricky_anchors.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/tricky_anchors.html new file mode 100644 index 00000000..0ec6204f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/tricky_anchors.html @@ -0,0 +1,11 @@ +

    with [brackets][] in text

    + +

    with [[brackets][]] in text

    + +

    full link [like](/this/) in text

    + +

    full link to img like is ok

    + +

    [only open bracket(/in/) text

    + +

    only close bracket text](/url/)

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/tricky_anchors.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/tricky_anchors.json new file mode 100644 index 00000000..cd92d155 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/tricky_anchors.json @@ -0,0 +1,29 @@ +["html", ["p", ["a", { + "href": "/url/" +}, +"with [brackets][] in text"]], + ["p", ["a", { + "href": "/url/", + "title": "a title" + }, + "with [[brackets][]] in text"]], + ["p", ["a", { + "href": "/url/" + }, + "full link [like](/this/) in text"]], + ["p", ["a", { + "href": "/url/" + }, + "full link to img ", ["img", { + "src": "/this/", + "alt": "like" + }], " is ok"]], + ["p", "[only open ", ["a", { + "href": "/url/", + "title": "a title" + }, + "bracket(/in/) text"]], + ["p", ["a", { + "href": "/in/" + }, + "only close bracket"], " text](/url/)"]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/tricky_anchors.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/tricky_anchors.text new file mode 100644 index 00000000..217f6855 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/tricky_anchors.text @@ -0,0 +1,11 @@ +[with [brackets][] in text](/url/) + +[with [[brackets][]] in text](/url/ "a title") + +[full link [like](/this/) in text](/url/) + +[full link to img ![like](/this/) is ok](/url/) + +[only open [bracket(/in/) text](/url/ 'a title') + +[only close bracket](/in/) text](/url/) diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/underline_in_autolink.html b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/underline_in_autolink.html new file mode 100644 index 00000000..9fef884f --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/underline_in_autolink.html @@ -0,0 +1,2 @@ +

    Eric wrote up a (long) intro to writing UDL definitions a while back on +his blog: http://blogs.activestate.com/ericp/2007/01/kid_adding_a_ne.html

    diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/underline_in_autolink.json b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/underline_in_autolink.json new file mode 100644 index 00000000..71dba013 --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/underline_in_autolink.json @@ -0,0 +1,4 @@ +["html", ["p", "Eric wrote up a (long) intro to writing UDL definitions a while back on\u000ahis blog: ", ["a", { + "href": "http://blogs.activestate.com/ericp/2007/01/kid_adding_a_ne.html" +}, +"http://blogs.activestate.com/ericp/2007/01/kid_adding_a_ne.html"]]] diff --git a/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/underline_in_autolink.text b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/underline_in_autolink.text new file mode 100644 index 00000000..58ae3e0d --- /dev/null +++ b/node_modules/markdown/test/fixtures/docs-pythonmarkdown2-tm-cases-pass/underline_in_autolink.text @@ -0,0 +1,2 @@ +Eric wrote up a (long) intro to writing UDL definitions a while back on +his blog: diff --git a/node_modules/markdown/test/interface.t.js b/node_modules/markdown/test/interface.t.js new file mode 100644 index 00000000..5e571d89 --- /dev/null +++ b/node_modules/markdown/test/interface.t.js @@ -0,0 +1,28 @@ +var markdown = require('Markdown'); + +function clone_array( input ) { + eval( "var tmp = " + input.toSource() ); + return tmp; +} + +tests = { + test_arguments_untouched: function() { + var input = "A [link][id] by id.\n\n[id]: http://google.com", + tree = markdown.parse( input ), + clone = clone_array( tree ); + + + var output = markdown.toHTML( tree ); + + asserts.same( tree, clone, "tree isn't modified" ); + // We had a problem where we would acidentally remove the references + // property from the root. We want to check the output is the same when + // called twice. + asserts.same( markdown.toHTML( tree ), output, "output is consistent" ); + } +} + +if (require.main === module) { + var asserts = require('test').asserts; + require('test').runner(tests); +} diff --git a/node_modules/markdown/test/regressions.t.js b/node_modules/markdown/test/regressions.t.js new file mode 100644 index 00000000..1602de51 --- /dev/null +++ b/node_modules/markdown/test/regressions.t.js @@ -0,0 +1,510 @@ +var Markdown = require('Markdown').Markdown, + mk_block = Markdown.mk_block; + +var tests = { + meta: function(fn) { + return function() { fn( new Markdown ) } + } +}; + +tests = { + test_split_block: tests.meta(function(md) { + asserts.same( + md.split_blocks( "# h1 #\n\npara1\npara1L2\n \n\n\n\npara2\n" ), + [mk_block( "# h1 #", "\n\n", 1 ), + mk_block( "para1\npara1L2", "\n \n\n\n\n", 3 ), + mk_block( "para2", "\n", 9 ) + ], + "split_block should record trailing newlines"); + + asserts.same( + md.split_blocks( "\n\n# heading #\n\npara\n" ), + [mk_block( "# heading #", "\n\n", 3 ), + mk_block( "para", "\n", 5 ) + ], + "split_block should ignore leading newlines"); + }), + + test_headers: tests.meta(function(md) { + var h1 = md.dialect.block.atxHeader( "# h1 #\n\n", [] ), + h2; + + asserts.same( + h1, + md.dialect.block.setextHeader( "h1\n===\n\n", [] ), + "Atx and Setext style H1s should produce the same output" ); + + asserts.same( + md.dialect.block.atxHeader("# h1\n\n"), + h1, + "Closing # optional on atxHeader"); + + asserts.same( + h2 = md.dialect.block.atxHeader( "## h2\n\n", [] ), + [["header", {level: 2}, "h2"]], + "Atx h2 has right level"); + + asserts.same( + h2, + md.dialect.block.setextHeader( "h2\n---\n\n", [] ), + "Atx and Setext style H2s should produce the same output" ); + + }), + + test_code: tests.meta(function(md) { + var code = md.dialect.block.code, + next = [ mk_block("next") ]; + + asserts.same( + code.call( md, mk_block(" foo\n bar"), next ), + [["code_block", "foo\nbar" ]], + "Code block correct"); + + asserts.same( + next, [mk_block("next")], + "next untouched when its not code"); + + next = []; + asserts.same( + code.call( md, mk_block(" foo\n bar"), next ), + [["code_block", "foo" ]], + "Code block correct for abutting para"); + + asserts.same( + next, [mk_block(" bar")], + "paragraph put back into next block"); + + asserts.same( + code.call( md, mk_block(" foo"), [mk_block(" bar"), ] ), + [["code_block", "foo\n\nbar" ]], + "adjacent code blocks "); + + asserts.same( + code.call( md, mk_block(" foo","\n \n \n"), [mk_block(" bar"), ] ), + [["code_block", "foo\n\n\nbar" ]], + "adjacent code blocks preserve correct number of empty lines"); + + }), + + test_bulletlist: tests.meta(function(md) { + var bl = function() { return md.dialect.block.lists.apply(md, arguments) }; + + asserts.same( + bl( mk_block("* foo\n* bar"), [] ), + [ [ "bulletlist", [ "listitem", "foo" ], [ "listitem", "bar" ] ] ], + "single line bullets"); + + asserts.same( + bl( mk_block("* [text](url)" ), [] ), + [ [ "bulletlist", [ "listitem", [ "link", { href: "url" }, "text" ] ] ] ], + "link in bullet"); + + asserts.same( + bl( mk_block("* foo\nbaz\n* bar\nbaz"), [] ), + [ [ "bulletlist", [ "listitem", "foo\nbaz" ], [ "listitem", "bar\nbaz" ] ] ], + "multiline lazy bullets"); + + asserts.same( + bl( mk_block("* foo\n baz\n* bar\n baz"), [] ), + [ [ "bulletlist", [ "listitem", "foo\nbaz" ], [ "listitem", "bar\nbaz" ] ] ], + "multiline tidy bullets"); + + asserts.same( + bl( mk_block("* foo\n baz"), [] ), + [ [ "bulletlist", [ "listitem", "foo\n baz" ] ] ], + "only trim 4 spaces from the start of the line"); + + /* Test wrong: should end up with 3 nested lists here + asserts.same( + bl( mk_block(" * one\n * two\n * three" ), [] ), + [ [ "bulletlist", [ "listitem", "one" ], [ "listitem", "two" ], [ "listitem", "three" ] ] ], + "bullets can be indented up to three spaces"); + */ + + asserts.same( + bl( mk_block(" * one"), [ mk_block(" two") ] ), + [ [ "bulletlist", [ "listitem", [ "para", "one" ], [ "para", "two" ] ] ] ], + "loose bullet lists can have multiple paragraphs"); + + /* Case: no space after bullet - not a list + | *↵ + |foo + */ + asserts.same( + bl( mk_block(" *\nfoo") ), + undefined, + "Space required after bullet to trigger list"); + + /* Case: note the space after the bullet + | *␣ + |foo + |bar + */ + asserts.same( + bl( mk_block(" * \nfoo\nbar"), [ ] ), + [ [ "bulletlist", [ "listitem", "foo\nbar" ] ] ], + "space+continuation lines"); + + + /* Case I: + | * foo + | * bar + | * baz + */ + asserts.same( + bl( mk_block(" * foo\n" + + " * bar\n" + + " * baz"), + [] ), + [ [ "bulletlist", + [ "listitem", + "foo", + [ "bulletlist", + [ "listitem", + "bar", + [ "bulletlist", + [ "listitem", "baz" ] + ] + ] + ] + ] + ] ], + "Interesting indented lists I"); + + /* Case II: + | * foo + | * bar + | * baz + */ + asserts.same( + bl( mk_block(" * foo\n * bar\n * baz"), [] ), + [ [ "bulletlist", + [ "listitem", + "foo", + [ "bulletlist", + [ "listitem", "bar" ] + ] + ], + [ "listitem", "baz" ] + ] ], + "Interesting indented lists II"); + + /* Case III: + | * foo + | * bar + |* baz + | * fnord + */ + asserts.same( + bl( mk_block(" * foo\n * bar\n* baz\n * fnord"), [] ), + [ [ "bulletlist", + [ "listitem", + "foo", + [ "bulletlist", + [ "listitem", "bar" ], + [ "listitem", "baz" ], + [ "listitem", "fnord" ] + ] + ] + ] ], + "Interesting indented lists III"); + + /* Case IV: + | * foo + | + | 1. bar + */ + asserts.same( + bl( mk_block(" * foo"), [ mk_block(" 1. bar\n") ] ), + [ [ "bulletlist", + ["listitem", ["para", "foo"] ], + ["listitem", ["para", "bar"] ] + ] ], + "Different lists at same indent IV"); + + /* Case V: + | * foo + | * bar + | * baz + */ + asserts.same( + bl( mk_block(" * foo\n * bar\n * baz"), [] ), + [ [ "bulletlist", + [ "listitem", + "foo", + [ "bulletlist", + ["listitem", "bar"], + ["listitem", "baz"], + ] + ] + ] ], + "Indenting Case V") + + /* Case VI: deep nesting + |* one + | * two + | * three + | * four + */ + asserts.same( + bl( mk_block("* one\n * two\n * three\n * four"), [] ), + [ [ "bulletlist", + [ "listitem", + "one", + [ "bulletlist", + [ "listitem", + "two", + [ "bulletlist", + [ "listitem", + "three", + [ "bulletlist", + [ "listitem", "four" ] + ] + ] + ] + ] + ] + ] + ] ], + "deep nested lists VI") + + /* Case VII: This one is just fruity! + | * foo + | * bar + | * baz + |* HATE + | * flibble + | * quxx + | * nest? + | * where + | * am + | * i? + */ + asserts.same( + bl( mk_block(" * foo\n" + + " * bar\n" + + " * baz\n" + + "* HATE\n" + + " * flibble\n" + + " * quxx\n" + + " * nest?\n" + + " * where\n" + + " * am\n" + + " * i?"), + [] ), + [ [ "bulletlist", + [ "listitem", + "foo", + [ "bulletlist", + ["listitem", "bar"], + ["listitem", "baz"], + ["listitem", "HATE"], + ["listitem", "flibble"] + ] + ], + [ "listitem", + "quxx", + [ "bulletlist", + [ "listitem", + "nest?", + [ "bulletlist", + ["listitem", "where"], + ["listitem", "am"], + ["listitem", "i?"] + ] + ] + ] + ] + ] ], + "Indenting Case VII"); + + /* Case VIII: Deep nesting + code block + | * one + | * two + | * three + | * four + | + | foo + */ + asserts.same( + bl( mk_block(" * one\n" + + " 1. two\n" + + " * three\n" + + " * four", + "\n\n"), + [ mk_block(" foo") ] ), + [ [ "bulletlist", + [ "listitem", + ["para", "one"], + [ "numberlist", + [ "listitem", + ["para", "two"], + [ "bulletlist", + [ "listitem", + [ "para", "three\n * four"], + ["code_block", "foo"] + ] + ] + ] + ] + ] + ] ], + "Case VIII: Deep nesting and code block"); + + }), + + test_horizRule: tests.meta(function(md) { + var hr = md.dialect.block.horizRule, + strs = ["---", "_ __", "** ** **", "--- "]; + strs.forEach( function(s) { + asserts.same( + hr.call( md, mk_block(s), [] ), + [ [ "hr" ] ], + "simple hr from " + uneval(s)); + }); + }), + + test_blockquote: tests.meta(function(md) { + var bq = md.dialect.block.blockquote; + asserts.same( + bq.call( md, mk_block("> foo\n> bar"), [] ), + [ ["blockquote", ["para", "foo\nbar"] ] ], + "simple blockquote"); + + // Note: this tests horizRule as well through block processing. + asserts.same( + bq.call( md, mk_block("> foo\n> bar\n>\n>- - - "), [] ), + [ ["blockquote", + ["para", "foo\nbar"], + ["hr"] + ] ], + "blockquote with interesting content"); + + }), + + test_referenceDefn: tests.meta(function(md) { + var rd = md.dialect.block.referenceDefn; + + [ '[id]: http://example.com/ "Optional Title Here"', + "[id]: http://example.com/ 'Optional Title Here'", + '[id]: http://example.com/ (Optional Title Here)' + ].forEach( function(s) { + md.tree = ["markdown"]; + + asserts.same(rd.call( md, mk_block(s) ), [], "ref processed"); + + asserts.same(md.tree[ 1 ].references, + { "id": { href: "http://example.com/", title: "Optional Title Here" } }, + "reference extracted"); + }); + + // Check a para abbuting a ref works right + md.tree = ["markdown"]; + var next = []; + asserts.same(rd.call( md, mk_block("[id]: example.com\npara"), next ), [], "ref processed"); + asserts.same(md.tree[ 1 ].references, { "id": { href: "example.com" } }, "reference extracted"); + asserts.same(next, [ mk_block("para") ], "paragraph put back into blocks"); + + }), + + test_inline_br: tests.meta(function(md) { + asserts.same( + md.processInline("foo \n\\[bar"), + [ "foo", ["linebreak"], "[bar" ], "linebreak+escape"); + }), + + test_inline_escape: tests.meta(function(md) { + asserts.same( md.processInline("\\bar"), [ "\\bar" ], "invalid escape" ); + asserts.same( md.processInline("\\*foo*"), [ "*foo*" ], "escaped em" ); + }), + + test_inline_code: tests.meta(function(md) { + asserts.same( md.processInline("`bar`"), [ ["inlinecode", "bar" ] ], "code I" ); + asserts.same( md.processInline("``b`ar``"), [ ["inlinecode", "b`ar" ] ], "code II" ); + asserts.same( md.processInline("```bar``` baz"), [ ["inlinecode", "bar" ], " baz" ], "code III" ); + }), + + test_inline_strong_em: tests.meta(function(md) { + // Yay for horrible edge cases >_< + asserts.same( md.processInline("foo *abc* bar"), [ "foo ", ["em", "abc" ], " bar" ], "strong/em I" ); + asserts.same( md.processInline("*abc `code`"), [ "*abc ", ["inlinecode", "code" ] ], "strong/em II" ); + asserts.same( md.processInline("*abc**def* after"), [ ["em", "abc**def" ], " after" ], "strong/em III" ); + asserts.same( md.processInline("*em **strong * wtf**"), [ ["em", "em **strong " ], " wtf**" ], "strong/em IV" ); + asserts.same( md.processInline("*foo _b*a*r baz"), [ [ "em", "foo _b" ], "a*r baz" ], "strong/em V" ); + }), + + test_inline_img: tests.meta(function(md) { + + asserts.same( md.processInline( "![alt] (url)" ), + [ [ "img", { href: "url", alt: "alt" } ] ], + "inline img I" ); + + asserts.same( md.processInline( "![alt](url 'title')" ), + [ [ "img", { href: "url", alt: "alt", title: "title" } ] ], + "inline img II" ); + + asserts.same( md.processInline( "![alt] (url 'tit'le') after')" ), + [ [ "img", { href: "url", alt: "alt", title: "tit'le" } ], " after')" ], + "inline img III" ); + + asserts.same( md.processInline( "![alt] (url \"title\")" ), + [ [ "img", { href: "url", alt: "alt", title: "title" } ] ], + "inline img IV" ); + + asserts.same( md.processInline( "![alt][id]" ), + [ [ "img_ref", { ref: "id", alt: "alt", text: "![alt][id]" } ] ], + "ref img I" ); + + asserts.same( md.processInline( "![alt] [id]" ), + [ [ "img_ref", { ref: "id", alt: "alt", text: "![alt] [id]" } ] ], + "ref img II" ); + }), + + test_inline_link: tests.meta(function(md) { + + asserts.same( md.processInline( "[text] (url)" ), + [ [ "link", { href: "url" }, "text" ] ], + "inline link I" ); + + asserts.same( md.processInline( "[text](url 'title')" ), + [ [ "link", { href: "url", title: "title" }, "text" ] ], + "inline link II" ); + + asserts.same( md.processInline( "[text](url 'tit'le') after')" ), + [ [ "link", { href: "url", title: "tit'le" }, "text" ], " after')" ], + "inline link III" ); + + asserts.same( md.processInline( "[text](url \"title\")" ), + [ [ "link", { href: "url", title: "title" }, "text" ] ], + "inline link IV" ); + + asserts.same( md.processInline( "[text][id]" ), + [ [ "link_ref", { ref: "id", original: "[text][id]" }, "text" ] ], + "ref link I" ); + + asserts.same( md.processInline( "[text] [id]" ), + [ [ "link_ref", { ref: "id", original: "[text] [id]" }, "text" ] ], + "ref link II" ); + }), + + test_inline_autolink: tests.meta(function(md) { + + asserts.same( md.processInline( "" ), + [ [ "link", { href: "http://foo.com" }, "http://foo.com" ] ], + "autolink I" ); + + asserts.same( md.processInline( "" ), + [ [ "link", { href: "mailto:foo@bar.com" }, "foo@bar.com" ] ], + "autolink II" ); + + asserts.same( md.processInline( "" ), + [ [ "link", { href: "mailto:foo@bar.com" }, "foo@bar.com" ] ], + "autolink III" ); + }), +} + + +if (require.main === module) { + var asserts = require('test').asserts; + require('test').runner(tests); +} diff --git a/node_modules/narcissus.js b/node_modules/narcissus.js new file mode 100644 index 00000000..ea9c48f0 --- /dev/null +++ b/node_modules/narcissus.js @@ -0,0 +1,31 @@ +/* + * Include the Mozilla Narcissus JavaScript parser. + */ + +(function(global) { + + if (typeof require !== 'undefined') { + if (typeof Narcissus === 'undefined') { + Narcissus = {}; + + require("narcissus/lib/jsdefs"); + + // workaround for rhino, which will throw an exception when trying + // to eval a const declaration + if (Narcissus.definitions.consts) try { + eval(Narcissus.definitions.consts); + } + catch (e) { + Narcissus.definitions.consts = Narcissus.definitions.consts.replace('const ', 'var '); + } + + //require("jsecma5"); + //require("jsmods.js"); + require("narcissus/lib/jslex"); + require("narcissus/lib/jsparse"); + } + + exports.Narcissus = Narcissus; + } + +})(global|this); \ No newline at end of file diff --git a/node_modules/narcissus/LICENSE b/node_modules/narcissus/LICENSE new file mode 100644 index 00000000..173bdc47 --- /dev/null +++ b/node_modules/narcissus/LICENSE @@ -0,0 +1,5 @@ +This software is available under your choice of the following licenses: + + * MPL 1.1 or later: http://www.mozilla.org/MPL/ + * GPL 2.0 or later: http://www.gnu.org/licenses/gpl.html + * LGPL 2.1 or later: http://www.gnu.org/licenses/lgpl.html diff --git a/node_modules/narcissus/README.md b/node_modules/narcissus/README.md new file mode 100644 index 00000000..02e7daa1 --- /dev/null +++ b/node_modules/narcissus/README.md @@ -0,0 +1,21 @@ +# Narcissus + +Narcissus is a JavaScript interpreter written in pure JavaScript (i.e., a [meta-circular evaluator](http://en.wikipedia.org/wiki/Meta-circular_evaluator)), using the [SpiderMonkey](http://www.mozilla.org/js/spidermonkey/) engine. + +Originally a proof-of-concept by [Brendan Eich](http://brendaneich.com/), Narcissus is being revived as a test-bed for rapidly prototyping new language features for the JavaScript language (as well as the ECMAScript standard). + +# Documentation + +Documentation can be found on the [Narcissus wiki](https://github.com/mozilla/narcissus/wiki). + +# Contributors + +* Tom Austin +* Brendan Eich +* Andreas Gal +* Shu-yu Guo +* Dave Herman +* Bruno Jouhier +* Gregor Richards +* Dimitris Vardoulakis +* Patrick Walton diff --git a/node_modules/narcissus/harmony-tests/README.txt b/node_modules/narcissus/harmony-tests/README.txt new file mode 100644 index 00000000..f353a925 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/README.txt @@ -0,0 +1,17 @@ +This directory contains tests for experimental Harmony features. + +NOTE: Please don't fork this test suite without talking to me first! + +I purposefully created almost no test harness whatsoever -- just a stupid shell +script that uses directory structure to figure out expected results. This is +because: + +a) I don't want to write Yet Another Test Harness; and + +b) I'd like these tests to get eaten up by some other test suite eventually. + +So *please* talk to me first before forking; it's probably much better to +adapt these tests directly. + +Dave Herman +dherman@mozilla.com diff --git a/node_modules/narcissus/harmony-tests/fail-execute/eval-export.js b/node_modules/narcissus/harmony-tests/fail-execute/eval-export.js new file mode 100644 index 00000000..83f8c249 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-execute/eval-export.js @@ -0,0 +1 @@ +eval("var x = 42; export x;"); diff --git a/node_modules/narcissus/harmony-tests/fail-execute/eval-resolve1.js b/node_modules/narcissus/harmony-tests/fail-execute/eval-resolve1.js new file mode 100644 index 00000000..0bdcc1a1 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-execute/eval-resolve1.js @@ -0,0 +1 @@ +eval("xyzzx") diff --git a/node_modules/narcissus/harmony-tests/fail-execute/eval-resolve2.js b/node_modules/narcissus/harmony-tests/fail-execute/eval-resolve2.js new file mode 100644 index 00000000..d6474648 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-execute/eval-resolve2.js @@ -0,0 +1 @@ +(function(x) { return eval("xyzzx") })("foo"); diff --git a/node_modules/narcissus/harmony-tests/fail-execute/module-uninit-read.js b/node_modules/narcissus/harmony-tests/fail-execute/module-uninit-read.js new file mode 100644 index 00000000..8cca9092 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-execute/module-uninit-read.js @@ -0,0 +1,8 @@ +module A { + import B.foo; + var x = foo; +} + +module B { + export var foo = 12; +} diff --git a/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle1.js b/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle1.js new file mode 100644 index 00000000..b7d4f86d --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle1.js @@ -0,0 +1,3 @@ +module M { + export M.foo; +} diff --git a/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle2.js b/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle2.js new file mode 100644 index 00000000..7caf42bf --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle2.js @@ -0,0 +1,7 @@ +module M { + export N.foo; +} + +module N { + export M.foo; +} diff --git a/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle3.js b/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle3.js new file mode 100644 index 00000000..b4b35cbc --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle3.js @@ -0,0 +1,7 @@ +module M { + export { foo: N.bar }; +} + +module N { + export { bar: M.foo }; +} diff --git a/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle4.js b/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle4.js new file mode 100644 index 00000000..db014b14 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-resolve/export-cycle4.js @@ -0,0 +1,15 @@ +module M { + export { foo: N.bar }; +} + +module N { + export { bar: O.baz }; +} + +module O { + export { baz: P.buz }; +} + +module P { + export { buz: M.foo }; +} diff --git a/node_modules/narcissus/harmony-tests/fail-resolve/export-unbound-var.js b/node_modules/narcissus/harmony-tests/fail-resolve/export-unbound-var.js new file mode 100644 index 00000000..148ff746 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-resolve/export-unbound-var.js @@ -0,0 +1 @@ +module M { export x } diff --git a/node_modules/narcissus/harmony-tests/fail-resolve/import-eval1.js b/node_modules/narcissus/harmony-tests/fail-resolve/import-eval1.js new file mode 100644 index 00000000..d8848d7b --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-resolve/import-eval1.js @@ -0,0 +1,2 @@ +eval("module M { export var foo = 42 }"); +import M.foo; diff --git a/node_modules/narcissus/harmony-tests/fail-resolve/import-eval2.js b/node_modules/narcissus/harmony-tests/fail-resolve/import-eval2.js new file mode 100644 index 00000000..4c3a726d --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-resolve/import-eval2.js @@ -0,0 +1,2 @@ +eval("module M { export var foo = 42 }"); +var x = M.foo; diff --git a/node_modules/narcissus/harmony-tests/fail-resolve/module-rebind-assignment1.js b/node_modules/narcissus/harmony-tests/fail-resolve/module-rebind-assignment1.js new file mode 100644 index 00000000..7ee5e17b --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-resolve/module-rebind-assignment1.js @@ -0,0 +1,5 @@ +module P { export module A { export var a = 12 } } + +module B = P.A + +B.a = 13; diff --git a/node_modules/narcissus/harmony-tests/fail-resolve/unbound-read.js b/node_modules/narcissus/harmony-tests/fail-resolve/unbound-read.js new file mode 100644 index 00000000..ebfbbb3a --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-resolve/unbound-read.js @@ -0,0 +1 @@ +var foo = someUnboundVariable; diff --git a/node_modules/narcissus/harmony-tests/fail-resolve/unbound-write.js b/node_modules/narcissus/harmony-tests/fail-resolve/unbound-write.js new file mode 100644 index 00000000..8f9dd8fc --- /dev/null +++ b/node_modules/narcissus/harmony-tests/fail-resolve/unbound-write.js @@ -0,0 +1 @@ +someUnboundVariable = 12; diff --git a/node_modules/narcissus/harmony-tests/run.sh b/node_modules/narcissus/harmony-tests/run.sh new file mode 100755 index 00000000..ec27881d --- /dev/null +++ b/node_modules/narcissus/harmony-tests/run.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +HERE=`dirname $0` +ROOT=$HERE/.. + +cd $ROOT + +FAILURES= + +################################################################################ + +echo Running harmony-tests/succeed... + +SUCCEED_PASS=0 +SUCCEED_FAIL=0 + +for f in harmony-tests/succeed/*.js ; do + ./njs -H -f $f >/dev/null 2>&1 + if [ $? -eq 0 ]; then + SUCCEED_PASS=$(($SUCCEED_PASS + 1)) + else + SUCCEED_FAIL=$(($SUCCEED_FAIL + 1)) + FAILURES="$FAILURES $f" + fi +done + +echo "==> $SUCCEED_PASS passed, $SUCCEED_FAIL failed." + +################################################################################ + +echo +echo Running harmony-tests/fail-resolve... + +FAIL_RESOLVE_PASS=0 +FAIL_RESOLVE_FAIL=0 + +for f in harmony-tests/fail-resolve/*.js ; do + ./njs -H -E "Narcissus.resolver.resolve(Narcissus.parser.parse(snarf('$f')),Narcissus.interpreter.globalStaticEnv)" >/dev/null 2>&1 + if [ $? -eq 0 ]; then + FAIL_RESOLVE_FAIL=$((FAIL_RESOLVE_FAIL + 1)) + FAILURES="$FAILURES $f" + else + FAIL_RESOLVE_PASS=$((FAIL_RESOLVE_PASS + 1)) + fi +done + +echo "==> $FAIL_RESOLVE_PASS passed, $FAIL_RESOLVE_FAIL failed." + +################################################################################ + +echo +echo Running harmony-tests/fail-execute... + +FAIL_EXECUTE_PASS=0 +FAIL_EXECUTE_FAIL=0 + +for f in harmony-tests/fail-execute ; do + ./njs -H -f $f >/dev/null 2>&1 + if [ $? -eq 0 ]; then + FAIL_EXECUTE_FAIL=$(($FAIL_EXECUTE_FAIL + 1)) + FAILURES="$FAILURES $f" + else + FAIL_EXECUTE_PASS=$(($FAIL_EXECUTE_PASS + 1)) + fi +done + +echo "==> $FAIL_EXECUTE_PASS passed, $FAIL_EXECUTE_FAIL failed." + +################################################################################ + +echo +echo TOTAL: + +TOTAL_PASS=$(($SUCCEED_PASS + $FAIL_EXECUTE_PASS + $FAIL_RESOLVE_PASS)) +TOTAL_FAIL=$(($SUCCEED_FAIL + $FAIL_EXECUTE_FAIL + $FAIL_RESOLVE_FAIL)) + +echo "==> $TOTAL_PASS passed, $TOTAL_FAIL failed." + +if [ $TOTAL_FAIL -gt 0 ]; then + echo + echo Failures: + for f in $FAILURES ; do + echo " $f" + done + exit 1 +else + exit 0 +fi diff --git a/node_modules/narcissus/harmony-tests/succeed/eval-import1.js b/node_modules/narcissus/harmony-tests/succeed/eval-import1.js new file mode 100644 index 00000000..64f51a29 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/eval-import1.js @@ -0,0 +1,5 @@ +module M { + export var foo = 42; +} + +assertEq(eval("import M.foo; foo"), 42); diff --git a/node_modules/narcissus/harmony-tests/succeed/eval-import2.js b/node_modules/narcissus/harmony-tests/succeed/eval-import2.js new file mode 100644 index 00000000..af6d8eeb --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/eval-import2.js @@ -0,0 +1,5 @@ +module M { + export var foo = "foo"; +} + +assertEq(eval("module M { export var bar = 'bar' } import M.bar; bar"), "bar"); diff --git a/node_modules/narcissus/harmony-tests/succeed/eval-module1.js b/node_modules/narcissus/harmony-tests/succeed/eval-module1.js new file mode 100644 index 00000000..ba97819e --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/eval-module1.js @@ -0,0 +1,9 @@ +module M { + export var foo = "foo"; +} + +var foo = M.foo; +var bar = eval("module M { export var bar = 'bar'; } M.bar"); + +assertEq(foo, "foo"); +assertEq(bar, "bar"); diff --git a/node_modules/narcissus/harmony-tests/succeed/eval-module2.js b/node_modules/narcissus/harmony-tests/succeed/eval-module2.js new file mode 100644 index 00000000..be217222 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/eval-module2.js @@ -0,0 +1,4 @@ +var M1 = eval("module M { } M"); +var M2 = eval("module M { } M"); + +assertEq(M1 === M2, false); diff --git a/node_modules/narcissus/harmony-tests/succeed/eval-resolve1.js b/node_modules/narcissus/harmony-tests/succeed/eval-resolve1.js new file mode 100644 index 00000000..46143204 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/eval-resolve1.js @@ -0,0 +1,5 @@ +var foo = 42; + +var myfoo = eval("foo"); + +assertEq(foo, myfoo); diff --git a/node_modules/narcissus/harmony-tests/succeed/eval-resolve2.js b/node_modules/narcissus/harmony-tests/succeed/eval-resolve2.js new file mode 100644 index 00000000..69a4023f --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/eval-resolve2.js @@ -0,0 +1,3 @@ +var foo = (function(x) { return eval("x") })("foo"); + +assertEq(foo, "foo"); diff --git a/node_modules/narcissus/harmony-tests/succeed/export-bound-var.js b/node_modules/narcissus/harmony-tests/succeed/export-bound-var.js new file mode 100644 index 00000000..1fea449c --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/export-bound-var.js @@ -0,0 +1,12 @@ +module M { + import N.x; + export x; +} + +module N { + var x = 42; + export x; +} + +assertEq(M.x, 42); +assertEq(N.x, 42); diff --git a/node_modules/narcissus/harmony-tests/succeed/export-var.js b/node_modules/narcissus/harmony-tests/succeed/export-var.js new file mode 100644 index 00000000..bf1a9eb1 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/export-var.js @@ -0,0 +1,5 @@ +module M { + export var foo = 42; +} + +assertEq(M.foo, 42); diff --git a/node_modules/narcissus/harmony-tests/succeed/global-this.js b/node_modules/narcissus/harmony-tests/succeed/global-this.js new file mode 100644 index 00000000..4f9f9d33 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/global-this.js @@ -0,0 +1,3 @@ +var global = this; + +assertEq("global" in global, true); diff --git a/node_modules/narcissus/harmony-tests/succeed/incomplete-module1.js b/node_modules/narcissus/harmony-tests/succeed/incomplete-module1.js new file mode 100644 index 00000000..dd3aceea --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/incomplete-module1.js @@ -0,0 +1,8 @@ +var saved; + +module M { + saved = M; + export var foo = 42; +} + +assertEq("foo" in saved, true); diff --git a/node_modules/narcissus/harmony-tests/succeed/incomplete-module2.js b/node_modules/narcissus/harmony-tests/succeed/incomplete-module2.js new file mode 100644 index 00000000..dfa890bb --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/incomplete-module2.js @@ -0,0 +1,9 @@ +var saved; + +module M { + export var foo = 42; + var tmp = M; + saved = tmp.foo; +} + +assertEq(saved, 42); diff --git a/node_modules/narcissus/harmony-tests/succeed/module-completion.js b/node_modules/narcissus/harmony-tests/succeed/module-completion.js new file mode 100644 index 00000000..edb66130 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/module-completion.js @@ -0,0 +1 @@ +assertEq(eval("module M { export var foo = 42 }").foo, 42); diff --git a/node_modules/narcissus/harmony-tests/succeed/module-rebind1.js b/node_modules/narcissus/harmony-tests/succeed/module-rebind1.js new file mode 100644 index 00000000..8313b978 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/module-rebind1.js @@ -0,0 +1,8 @@ +module P { + module A { export var a = 12 } + export A +} + +module B = P.A + +assertEq(B.a, 12); diff --git a/node_modules/narcissus/harmony-tests/succeed/module-rebind2.js b/node_modules/narcissus/harmony-tests/succeed/module-rebind2.js new file mode 100644 index 00000000..e96dbbd9 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/module-rebind2.js @@ -0,0 +1,10 @@ +module P { + module A { export var a = 12 } + export A +} + +module B = P.A, C = P.A, D = P.A; + +assertEq(B.a, 12); +assertEq(C.a, 12); +assertEq(D.a, 12); diff --git a/node_modules/narcissus/harmony-tests/succeed/module-rebind3.js b/node_modules/narcissus/harmony-tests/succeed/module-rebind3.js new file mode 100644 index 00000000..fec298fd --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/module-rebind3.js @@ -0,0 +1,9 @@ +module M { + export var foo = 42; + export module N { + module M; + export var foo = M.foo + } +} + +assertEq(M.foo, M.N.foo); diff --git a/node_modules/narcissus/harmony-tests/succeed/module-this.js b/node_modules/narcissus/harmony-tests/succeed/module-this.js new file mode 100644 index 00000000..0e20dda1 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/module-this.js @@ -0,0 +1,8 @@ +var saved; + +module M { + saved = this; + export var foo = 42; +} + +assertEq("foo" in saved, true); diff --git a/node_modules/narcissus/harmony-tests/succeed/re-export1.js b/node_modules/narcissus/harmony-tests/succeed/re-export1.js new file mode 100644 index 00000000..7886c792 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/re-export1.js @@ -0,0 +1,18 @@ +module M { + export module N { + export var foo = 42; + export var bar = "hello world"; + } +} + +module Q { + export { + foo: M.N.bar, + bar: M.N.foo + } +} + +assertEq(Q.foo, "hello world"); +assertEq(Q.bar, 42); +assertEq(Q.foo, M.N.bar); +assertEq(Q.bar, M.N.foo); diff --git a/node_modules/narcissus/harmony-tests/succeed/re-export2.js b/node_modules/narcissus/harmony-tests/succeed/re-export2.js new file mode 100644 index 00000000..f115ac6e --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/re-export2.js @@ -0,0 +1,19 @@ +module M { + export module N { + export var foo = 42; + export var bar = "hello world"; + } +} + +module Q { + module MN = M.N; + export { + foo: MN.bar, + bar: MN.foo + } +} + +assertEq(Q.foo, "hello world"); +assertEq(Q.bar, 42); +assertEq(Q.foo, M.N.bar); +assertEq(Q.bar, M.N.foo); diff --git a/node_modules/narcissus/harmony-tests/succeed/uninitialized-module1.js b/node_modules/narcissus/harmony-tests/succeed/uninitialized-module1.js new file mode 100644 index 00000000..4996d82b --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/uninitialized-module1.js @@ -0,0 +1,7 @@ +var saved = M; + +module M { + export var foo = 42; +} + +assertEq(saved.foo, 42); diff --git a/node_modules/narcissus/harmony-tests/succeed/uninitialized-module2.js b/node_modules/narcissus/harmony-tests/succeed/uninitialized-module2.js new file mode 100644 index 00000000..04717059 --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/uninitialized-module2.js @@ -0,0 +1,9 @@ +var saved = M.N; + +module M { + export module N { + export var foo = 42; + } +} + +assertEq(saved.foo, 42); diff --git a/node_modules/narcissus/harmony-tests/succeed/uninitialized-module3.js b/node_modules/narcissus/harmony-tests/succeed/uninitialized-module3.js new file mode 100644 index 00000000..e535558c --- /dev/null +++ b/node_modules/narcissus/harmony-tests/succeed/uninitialized-module3.js @@ -0,0 +1,14 @@ +var saved; + +module M { + module N { + saved = M.O.P; + } + export module O { + export module P { + export var foo = 42; + } + } +} + +assertEq(saved.foo, 42); diff --git a/node_modules/narcissus/jstests b/node_modules/narcissus/jstests new file mode 100755 index 00000000..c62465bf --- /dev/null +++ b/node_modules/narcissus/jstests @@ -0,0 +1,44 @@ +#!/bin/sh + +# Root of the narcissus tree +NJS_HOME=`dirname $0` +NJS_HOME=`(cd $NJS_HOME; pwd)` + +# Fake information for the test harness's |xulRuntime| configuration object. +XUL_INFO=none:none:true + +if [ $# -eq 1 -a "$1" = "-h" ]; then + echo "usage: jstests [-h | -a | ...]" 1>&2 + echo " -h display this usage information and quit" 1>&2 + echo " -a run all but the slowest tests (those in xfail/narcissus-slow.txt)" 1>&2 + echo " path to individual test (relative to test directory)" 1>&2 + echo "" 1>&2 + echo "With no arguments, jstests runs all tests except those listed in" 1>&2 + echo "xfail/narcissus-failures.txt, which includes all the tests listed in" 1>&2 + echo "xfail/narcissus-slow.txt." 1>&2 + echo "" 1>&2 + echo "The test directory is searched for either in NJS_TESTS or in" 1>&2 + echo "a tests/ subdirectory of the Narcissus home directory." + exit +elif [ $# -gt 0 -a "$1" = "-a" ]; then + shift + XFAIL=narcissus-slow.txt +else + XFAIL=narcissus-failures.txt +fi + +if [ ! -z $NJS_TESTS -a -d $NJS_TESTS ]; then + cd $NJS_TESTS +elif [ -d $NJS_HOME/tests ]; then + cd $NJS_HOME/tests +else + echo 'Expected a test directory in $NJS_TESTS or '"$NJS_HOME/tests." 1>&2 + echo "Run jstests -h for more information." 1>&2 + exit 1 +fi + +if [ $# -gt 0 ]; then + exec python jstests.py --xul-info=$XUL_INFO -s -o -d -j 4 $NJS_HOME/njs $* +else + exec python jstests.py --xul-info=$XUL_INFO -d -j 4 $NJS_HOME/njs -x $NJS_HOME/xfail/$XFAIL +fi diff --git a/node_modules/narcissus/lib.zip b/node_modules/narcissus/lib.zip new file mode 100644 index 00000000..9602252e Binary files /dev/null and b/node_modules/narcissus/lib.zip differ diff --git a/node_modules/narcissus/lib/decompiler.js b/node_modules/narcissus/lib/decompiler.js new file mode 100644 index 00000000..92946458 --- /dev/null +++ b/node_modules/narcissus/lib/decompiler.js @@ -0,0 +1,50 @@ +/* vim: set sw=4 ts=4 et tw=78: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Narcissus JavaScript engine. + * + * The Initial Developer of the Original Code is + * Brendan Eich . + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tom Austin + * Brendan Eich + * Shu-Yu Guo + * Dave Herman + * Dimitris Vardoulakis + * Patrick Walton + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +require("./jsdefs"); +require("./jslex"); +require("./jsparse"); +require("./jsdecomp"); + +for (var exp in Narcissus.decompiler) + exports[exp] = Narcissus.decompiler[exp]; diff --git a/node_modules/narcissus/lib/definitions.js b/node_modules/narcissus/lib/definitions.js new file mode 100644 index 00000000..4412b4a1 --- /dev/null +++ b/node_modules/narcissus/lib/definitions.js @@ -0,0 +1,47 @@ +/* vim: set sw=4 ts=4 et tw=78: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Narcissus JavaScript engine. + * + * The Initial Developer of the Original Code is + * Brendan Eich . + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tom Austin + * Brendan Eich + * Shu-Yu Guo + * Dave Herman + * Dimitris Vardoulakis + * Patrick Walton + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +require("./jsdefs"); + +for (var exp in Narcissus.definitions) + exports[exp] = Narcissus.definitions[exp]; diff --git a/node_modules/narcissus/lib/jsbrowser.js b/node_modules/narcissus/lib/jsbrowser.js new file mode 100644 index 00000000..eb03e05a --- /dev/null +++ b/node_modules/narcissus/lib/jsbrowser.js @@ -0,0 +1,65 @@ +/* -*- Mode: JS; tab-width: 4; indent-tabs-mode: nil; -*- + * vim: set sw=4 ts=8 et tw=78: +/* ***** BEGIN LICENSE BLOCK ***** + * + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Narcissus JavaScript engine. + * + * The Initial Developer of the Original Code is + * Brendan Eich . + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Narcissus - JS implemented in JS. + * + * Browser-specific tweaks needed for Narcissus to execute properly + */ + +// Prevent setTimeout from breaking out to SpiderMonkey +Narcissus.interpreter.globalBase.setTimeout = function(code, delay) { + var timeoutCode = (typeof code === "string") ? + function() { Narcissus.interpreter.evaluate(code); } : + code; + return setTimeout(timeoutCode, delay); +}; + +// Prevent setInterval from breaking out to SpiderMonkey +Narcissus.interpreter.globalBase.setInterval = function(code, delay) { + var timeoutCode = (typeof code === "string") ? + function() { Narcissus.interpreter.evaluate(code); } : + code; + return setInterval(timeoutCode, delay); +}; + +// Hack to avoid problems with the Image constructor in Narcissus. +Narcissus.interpreter.globalBase.Image = function() {}; + + diff --git a/node_modules/narcissus/lib/jsdecomp.js b/node_modules/narcissus/lib/jsdecomp.js new file mode 100644 index 00000000..8e178078 --- /dev/null +++ b/node_modules/narcissus/lib/jsdecomp.js @@ -0,0 +1,528 @@ +/* vim: set sw=4 ts=4 et tw=78: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Narcissus JavaScript engine. + * + * The Initial Developer of the Original Code is + * Brendan Eich . + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shu-Yu Guo + * Bruno Jouhier + * Gregor Richards + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Narcissus - JS implemented in JS. + * + * Decompiler and pretty-printer. + */ + +Narcissus.decompiler = (function() { + + const parser = Narcissus.parser; + const definitions = Narcissus.definitions; + const tokens = definitions.tokens; + + // Set constants in the local scope. + eval(definitions.consts); + + function indent(n, s) { + var ss = "", d = true; + + for (var i = 0, j = s.length; i < j; i++) { + if (d) + for (var k = 0; k < n; k++) + ss += " "; + ss += s[i]; + d = s[i] === '\n'; + } + + return ss; + } + + function isBlock(n) { + return n && (n.type === BLOCK); + } + + function isNonEmptyBlock(n) { + return isBlock(n) && n.children.length > 0; + } + + function nodeStr(n) { + return '"' + + n.value.replace(/\\/g, "\\\\") + .replace(/"/g, "\\\"") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + + '"'; + } + + function pp(n, d, inLetHead) { + var topScript = false; + + if (!n) + return ""; + if (!(n instanceof Object)) + return n; + if (!d) { + topScript = true; + d = 1; + } + + var p = ""; + + if (n.parenthesized) + p += "("; + + switch (n.type) { + case FUNCTION: + case GETTER: + case SETTER: + if (n.type === FUNCTION) + p += "function"; + else if (n.type === GETTER) + p += "get"; + else + p += "set"; + + p += (n.name ? " " + n.name : "") + "("; + for (var i = 0, j = n.params.length; i < j; i++) + p += (i > 0 ? ", " : "") + pp(n.params[i], d); + p += ") " + pp(n.body, d); + break; + + case SCRIPT: + case BLOCK: + var nc = n.children; + if (topScript) { + // No indentation. + for (var i = 0, j = nc.length; i < j; i++) { + if (i > 0) + p += "\n"; + p += pp(nc[i], d); + var eoc = p[p.length - 1]; + if (eoc != ";") + p += ";"; + } + + break; + } + + p += "{"; + if (n.id !== undefined) + p += " /* " + n.id + " */"; + p += "\n"; + for (var i = 0, j = nc.length; i < j; i++) { + if (i > 0) + p += "\n"; + p += indent(4, pp(nc[i], d)); + var eoc = p[p.length - 1]; + if (eoc != ";") + p += ";"; + } + p += "\n}"; + break; + + case LET_BLOCK: + p += "let (" + pp(n.variables, d, true) + ") "; + if (n.expression) + p += pp(n.expression, d); + else + p += pp(n.block, d); + break; + + case IF: + p += "if (" + pp(n.condition, d) + ") "; + + var tp = n.thenPart, ep = n.elsePart; + var b = isBlock(tp) || isBlock(ep); + if (!b) + p += "{\n"; + p += (b ? pp(tp, d) : indent(4, pp(tp, d))) + "\n"; + + if (ep) { + if (!b) + p += "} else {\n"; + else + p += " else "; + + p += (b ? pp(ep, d) : indent(4, pp(ep, d))) + "\n"; + } + if (!b) + p += "}"; + break; + + case SWITCH: + p += "switch (" + pp(n.discriminant, d) + ") {\n"; + for (var i = 0, j = n.cases.length; i < j; i++) { + var ca = n.cases[i]; + if (ca.type === CASE) + p += " case " + pp(ca.caseLabel, d) + ":\n"; + else + p += " default:\n"; + ps = pp(ca.statements, d); + p += ps.slice(2, ps.length - 2) + "\n"; + } + p += "}"; + break; + + case FOR: + p += "for (" + pp(n.setup, d) + "; " + + pp(n.condition, d) + "; " + + pp(n.update, d) + ") "; + + var pb = pp(n.body, d); + if (!isBlock(n.body)) + p += "{\n" + indent(4, pb) + ";\n}"; + else if (n.body) + p += pb; + break; + + case WHILE: + p += "while (" + pp(n.condition, d) + ") "; + + var pb = pp(n.body, d); + if (!isBlock(n.body)) + p += "{\n" + indent(4, pb) + ";\n}"; + else + p += pb; + break; + + case FOR_IN: + var u = n.varDecl; + p += n.isEach ? "for each (" : "for ("; + p += (u ? pp(u, d) : pp(n.iterator, d)) + " in " + + pp(n.object, d) + ") "; + + var pb = pp(n.body, d); + if (!isBlock(n.body)) + p += "{\n" + indent(4, pb) + ";\n}"; + else if (n.body) + p += pb; + break; + + case DO: + p += "do " + pp(n.body, d); + p += " while (" + pp(n.condition, d) + ");"; + break; + + case BREAK: + p += "break" + (n.label ? " " + n.label : "") + ";"; + break; + + case CONTINUE: + p += "continue" + (n.label ? " " + n.label : "") + ";"; + break; + + case TRY: + p += "try "; + p += pp(n.tryBlock, d); + for (var i = 0, j = n.catchClauses.length; i < j; i++) { + var t = n.catchClauses[i]; + p += " catch (" + pp(t.varName, d) + + (t.guard ? " if " + pp(t.guard, d) : "") + + ") "; + p += pp(t.block, d); + } + if (n.finallyBlock) { + p += " finally "; + p += pp(n.finallyBlock, d); + } + break; + + case THROW: + p += "throw " + pp(n.exception, d); + break; + + case RETURN: + p += "return"; + if (n.value) + p += " " + pp(n.value, d); + break; + + case YIELD: + p += "yield"; + if (n.value.type) + p += " " + pp(n.value, d); + break; + + case GENERATOR: + p += pp(n.expression, d) + " " + pp(n.tail, d); + break; + + case WITH: + p += "with (" + pp(n.object, d) + ") "; + p += pp(n.body, d); + break; + + case LET: + case VAR: + case CONST: + var nc = n.children; + if (!inLetHead) { + p += tokens[n.type] + " "; + } + for (var i = 0, j = nc.length; i < j; i++) { + if (i > 0) + p += ", "; + var u = nc[i]; + p += pp(u.name, d); + if (u.initializer) + p += " = " + pp(u.initializer, d); + } + break; + + case DEBUGGER: + p += "debugger NYI\n"; + break; + + case SEMICOLON: + if (n.expression) { + p += pp(n.expression, d) + ";"; + } + break; + + case LABEL: + p += n.label + ":\n" + pp(n.statement, d); + break; + + case COMMA: + case LIST: + var nc = n.children; + for (var i = 0, j = nc.length; i < j; i++) { + if (i > 0) + p += ", "; + p += pp(nc[i], d); + } + break; + + case ASSIGN: + var nc = n.children; + var t = n.assignOp; + p += pp(nc[0], d) + " " + (t ? tokens[t] : "") + "=" + + " " + pp(nc[1], d); + break; + + case HOOK: + var nc = n.children; + p += "(" + pp(nc[0], d) + " ? " + + pp(nc[1], d) + " : " + + pp(nc[2], d); + p += ")"; + break; + + case OR: + case AND: + var nc = n.children; + p += "(" + pp(nc[0], d) + " " + tokens[n.type] + " " + + pp(nc[1], d); + p += ")"; + break; + + case BITWISE_OR: + case BITWISE_XOR: + case BITWISE_AND: + case EQ: + case NE: + case STRICT_EQ: + case STRICT_NE: + case LT: + case LE: + case GE: + case GT: + case IN: + case INSTANCEOF: + case LSH: + case RSH: + case URSH: + case PLUS: + case MINUS: + case MUL: + case DIV: + case MOD: + var nc = n.children; + p += "(" + pp(nc[0], d) + " " + tokens[n.type] + " " + + pp(nc[1], d) + ")"; + break; + + case DELETE: + case VOID: + case TYPEOF: + p += tokens[n.type] + " " + pp(n.children[0], d); + break; + + case NOT: + case BITWISE_NOT: + p += tokens[n.type] + pp(n.children[0], d); + break; + + case UNARY_PLUS: + p += "+" + pp(n.children[0], d); + break; + + case UNARY_MINUS: + p += "-" + pp(n.children[0], d); + break; + + case INCREMENT: + case DECREMENT: + if (n.postfix) { + p += pp(n.children[0], d) + tokens[n.type]; + } else { + p += tokens[n.type] + pp(n.children[0], d); + } + break; + + case DOT: + var nc = n.children; + p += pp(nc[0], d) + "." + pp(nc[1], d); + break; + + case INDEX: + var nc = n.children; + p += pp(nc[0], d) + "[" + pp(nc[1], d) + "]"; + break; + + case CALL: + var nc = n.children; + p += pp(nc[0], d) + "(" + pp(nc[1], d) + ")"; + break; + + case NEW: + case NEW_WITH_ARGS: + var nc = n.children; + p += "new " + pp(nc[0], d); + if (nc[1]) + p += "(" + pp(nc[1], d) + ")"; + break; + + case ARRAY_INIT: + p += "["; + var nc = n.children; + for (var i = 0, j = nc.length; i < j; i++) { + if(nc[i]) + p += pp(nc[i], d); + p += "," + } + p += "]"; + break; + + case ARRAY_COMP: + p += "[" + pp (n.expression, d) + " "; + p += pp(n.tail, d); + p += "]"; + break; + + case COMP_TAIL: + var nc = n.children; + for (var i = 0, j = nc.length; i < j; i++) { + if (i > 0) + p += " "; + p += pp(nc[i], d); + } + if (n.guard) + p += " if (" + pp(n.guard, d) + ")"; + break; + + case OBJECT_INIT: + var nc = n.children; + if (nc[0] && nc[0].type === PROPERTY_INIT) + p += "{\n"; + else + p += "{"; + for (var i = 0, j = nc.length; i < j; i++) { + if (i > 0) { + p += ",\n"; + } + + var t = nc[i]; + if (t.type === PROPERTY_INIT) { + var tc = t.children; + var l; + // see if the left needs to be a string + if (tc[0].value === "" || /[^A-Za-z0-9_$]/.test(tc[0].value)) { + l = nodeStr(tc[0]); + } else { + l = pp(tc[0], d); + } + p += indent(4, l) + ": " + + indent(4, pp(tc[1], d)).substring(4); + } else { + p += indent(4, pp(t, d)); + } + } + p += "\n}"; + break; + + case NULL: + p += "null"; + break; + + case THIS: + p += "this"; + break; + + case TRUE: + p += "true"; + break; + + case FALSE: + p += "false"; + break; + + case IDENTIFIER: + case NUMBER: + case REGEXP: + p += n.value; + break; + + case STRING: + p += nodeStr(n); + break; + + case GROUP: + p += "(" + pp(n.children[0], d) + ")"; + break; + + default: + throw "PANIC: unknown operation " + tokens[n.type] + " " + n.toSource(); + } + + if (n.parenthesized) + p += ")"; + + return p; + } + + return { + pp: pp + }; + +}()); diff --git a/node_modules/narcissus/lib/jsdefs.js b/node_modules/narcissus/lib/jsdefs.js new file mode 100644 index 00000000..bb1a8103 --- /dev/null +++ b/node_modules/narcissus/lib/jsdefs.js @@ -0,0 +1,675 @@ +/* vim: set sw=4 ts=4 et tw=78: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Narcissus JavaScript engine. + * + * The Initial Developer of the Original Code is + * Brendan Eich . + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tom Austin + * Brendan Eich + * Shu-Yu Guo + * Dave Herman + * Dimitris Vardoulakis + * Patrick Walton + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Narcissus - JS implemented in JS. + * + * Well-known constants and lookup tables. Many consts are generated from the + * tokens table via eval to minimize redundancy, so consumers must be compiled + * separately to take advantage of the simple switch-case constant propagation + * done by SpiderMonkey. + */ + +(function() { + + var narcissus = { + options: { + version: 185, + }, + hostGlobal: this + }; + Narcissus = narcissus; +})(); + +Narcissus.definitions = (function() { + + var tokens = [ + // End of source. + "END", + + // Operators and punctuators. Some pair-wise order matters, e.g. (+, -) + // and (UNARY_PLUS, UNARY_MINUS). + "\n", ";", + ",", + "=", + "?", ":", "CONDITIONAL", + "||", + "&&", + "|", + "^", + "&", + "==", "!=", "===", "!==", + "<", "<=", ">=", ">", + "<<", ">>", ">>>", + "+", "-", + "*", "/", "%", + "!", "~", "UNARY_PLUS", "UNARY_MINUS", + "++", "--", + ".", + "[", "]", + "{", "}", + "(", ")", + + // Nonterminal tree node type codes. + "SCRIPT", "BLOCK", "LABEL", "FOR_IN", "CALL", "NEW_WITH_ARGS", "INDEX", + "ARRAY_INIT", "OBJECT_INIT", "PROPERTY_INIT", "GETTER", "SETTER", + "GROUP", "LIST", "LET_BLOCK", "ARRAY_COMP", "GENERATOR", "COMP_TAIL", + + // Terminals. + "IDENTIFIER", "NUMBER", "STRING", "REGEXP", + + // Keywords. + "break", + "case", "catch", "const", "continue", + "debugger", "default", "delete", "do", + "else", "export", + "false", "finally", "for", "function", + "if", "import", "in", "instanceof", + "let", "module", + "new", "null", + "return", + "switch", + "this", "throw", "true", "try", "typeof", + "var", "void", + "yield", + "while", "with", + ]; + + var statementStartTokens = [ + "break", + "const", "continue", + "debugger", "do", + "for", + "if", + "return", + "switch", + "throw", "try", + "var", + "yield", + "while", "with", + ]; + + // Whitespace characters (see ECMA-262 7.2) + var whitespaceChars = [ + // normal whitespace: + "\u0009", "\u000B", "\u000C", "\u0020", "\u00A0", "\uFEFF", + + // high-Unicode whitespace: + "\u1680", "\u180E", + "\u2000", "\u2001", "\u2002", "\u2003", "\u2004", "\u2005", "\u2006", + "\u2007", "\u2008", "\u2009", "\u200A", + "\u202F", "\u205F", "\u3000" + ]; + + var whitespace = {}; + for (var i = 0; i < whitespaceChars.length; i++) { + whitespace[whitespaceChars[i]] = true; + } + + // Operator and punctuator mapping from token to tree node type name. + // NB: because the lexer doesn't backtrack, all token prefixes must themselves + // be valid tokens (e.g. !== is acceptable because its prefixes are the valid + // tokens != and !). + var opTypeNames = { + '\n': "NEWLINE", + ';': "SEMICOLON", + ',': "COMMA", + '?': "HOOK", + ':': "COLON", + '||': "OR", + '&&': "AND", + '|': "BITWISE_OR", + '^': "BITWISE_XOR", + '&': "BITWISE_AND", + '===': "STRICT_EQ", + '==': "EQ", + '=': "ASSIGN", + '!==': "STRICT_NE", + '!=': "NE", + '<<': "LSH", + '<=': "LE", + '<': "LT", + '>>>': "URSH", + '>>': "RSH", + '>=': "GE", + '>': "GT", + '++': "INCREMENT", + '--': "DECREMENT", + '+': "PLUS", + '-': "MINUS", + '*': "MUL", + '/': "DIV", + '%': "MOD", + '!': "NOT", + '~': "BITWISE_NOT", + '.': "DOT", + '[': "LEFT_BRACKET", + ']': "RIGHT_BRACKET", + '{': "LEFT_CURLY", + '}': "RIGHT_CURLY", + '(': "LEFT_PAREN", + ')': "RIGHT_PAREN" + }; + + // Hash of keyword identifier to tokens index. NB: we must null __proto__ to + // avoid toString, etc. namespace pollution. + var keywords = {__proto__: null}; + + // Define const END, etc., based on the token names. Also map name to index. + var tokenIds = {}; + + // Building up a string to be eval'd in different contexts. + var consts = "const "; + for (var i = 0, j = tokens.length; i < j; i++) { + if (i > 0) + consts += ", "; + var t = tokens[i]; + var name; + if (/^[a-z]/.test(t)) { + name = t.toUpperCase(); + keywords[t] = i; + } else { + name = (/^\W/.test(t) ? opTypeNames[t] : t); + } + consts += name + " = " + i; + tokenIds[name] = i; + tokens[t] = i; + } + consts += ";"; + + var isStatementStartCode = {__proto__: null}; + for (i = 0, j = statementStartTokens.length; i < j; i++) + isStatementStartCode[keywords[statementStartTokens[i]]] = true; + + // Map assignment operators to their indexes in the tokens array. + var assignOps = ['|', '^', '&', '<<', '>>', '>>>', '+', '-', '*', '/', '%']; + + for (i = 0, j = assignOps.length; i < j; i++) { + t = assignOps[i]; + assignOps[t] = tokens[t]; + } + + function defineGetter(obj, prop, fn, dontDelete, dontEnum) { + Object.defineProperty(obj, prop, + { get: fn, configurable: !dontDelete, enumerable: !dontEnum }); + } + + function defineGetterSetter(obj, prop, getter, setter, dontDelete, dontEnum) { + Object.defineProperty(obj, prop, { + get: getter, + set: setter, + configurable: !dontDelete, + enumerable: !dontEnum + }); + } + + function defineMemoGetter(obj, prop, fn, dontDelete, dontEnum) { + Object.defineProperty(obj, prop, { + get: function() { + var val = fn(); + defineProperty(obj, prop, val, dontDelete, true, dontEnum); + return val; + }, + configurable: true, + enumerable: !dontEnum + }); + } + + function defineProperty(obj, prop, val, dontDelete, readOnly, dontEnum) { + Object.defineProperty(obj, prop, + { value: val, writable: !readOnly, configurable: !dontDelete, + enumerable: !dontEnum }); + } + + // Returns true if fn is a native function. (Note: SpiderMonkey specific.) + function isNativeCode(fn) { + // Relies on the toString method to identify native code. + return ((typeof fn) === "function") && fn.toString().match(/\[native code\]/); + } + + function getPropertyDescriptor(obj, name) { + while (obj) { + if (({}).hasOwnProperty.call(obj, name)) + return Object.getOwnPropertyDescriptor(obj, name); + obj = Object.getPrototypeOf(obj); + } + } + + function getPropertyNames(obj) { + var table = Object.create(null, {}); + while (obj) { + var names = Object.getOwnPropertyNames(obj); + for (var i = 0, n = names.length; i < n; i++) + table[names[i]] = true; + obj = Object.getPrototypeOf(obj); + } + return Object.keys(table); + } + + function getOwnProperties(obj) { + var map = {}; + for (var name in Object.getOwnPropertyNames(obj)) + map[name] = Object.getOwnPropertyDescriptor(obj, name); + return map; + } + + function blacklistHandler(target, blacklist) { + var mask = Object.create(null, {}); + var redirect = StringMap.create(blacklist).mapObject(function(name) { return mask; }); + return mixinHandler(redirect, target); + } + + function whitelistHandler(target, whitelist) { + var catchall = Object.create(null, {}); + var redirect = StringMap.create(whitelist).mapObject(function(name) { return target; }); + return mixinHandler(redirect, catchall); + } + + function mirrorHandler(target, writable) { + var handler = makePassthruHandler(target); + + var defineProperty = handler.defineProperty; + handler.defineProperty = function(name, desc) { + if (!desc.enumerable) + throw new Error("mirror property must be enumerable"); + if (!desc.configurable) + throw new Error("mirror property must be configurable"); + if (desc.writable !== writable) + throw new Error("mirror property must " + (writable ? "" : "not ") + "be writable"); + defineProperty(name, desc); + }; + + handler.fix = function() { }; + handler.getOwnPropertyDescriptor = handler.getPropertyDescriptor; + handler.getOwnPropertyNames = getPropertyNames.bind(handler, target); + handler.keys = handler.enumerate; + handler['delete'] = function() { return false; }; + handler.hasOwn = handler.has; + return handler; + } + + /* + * Mixin proxies break the single-inheritance model of prototypes, so + * the handler treats all properties as own-properties: + * + * X + * | + * +------------+------------+ + * | O | + * | | | + * | O O O | + * | | | | | + * | O O O O | + * | | | | | | + * | O O O O O | + * | | | | | | | + * +-(*)--(w)--(x)--(y)--(z)-+ + */ + + function mixinHandler(redirect, catchall) { + function targetFor(name) { + return hasOwn(redirect, name) ? redirect[name] : catchall; + } + + function getMuxPropertyDescriptor(name) { + var desc = getPropertyDescriptor(targetFor(name), name); + if (desc) + desc.configurable = true; + return desc; + } + + function getMuxPropertyNames() { + var names1 = Object.getOwnPropertyNames(redirect).filter(function(name) { + return name in redirect[name]; + }); + var names2 = getPropertyNames(catchall).filter(function(name) { + return !hasOwn(redirect, name); + }); + return names1.concat(names2); + } + + function enumerateMux() { + var result = Object.getOwnPropertyNames(redirect).filter(function(name) { + return name in redirect[name]; + }); + for (name in catchall) { + if (!hasOwn(redirect, name)) + result.push(name); + }; + return result; + } + + function hasMux(name) { + return name in targetFor(name); + } + + return { + getOwnPropertyDescriptor: getMuxPropertyDescriptor, + getPropertyDescriptor: getMuxPropertyDescriptor, + getOwnPropertyNames: getMuxPropertyNames, + defineProperty: function(name, desc) { + Object.defineProperty(targetFor(name), name, desc); + }, + "delete": function(name) { + var target = targetFor(name); + return delete target[name]; + }, + // FIXME: ha ha ha + fix: function() { }, + has: hasMux, + hasOwn: hasMux, + get: function(receiver, name) { + var target = targetFor(name); + return target[name]; + }, + set: function(receiver, name, val) { + var target = targetFor(name); + target[name] = val; + return true; + }, + enumerate: enumerateMux, + keys: enumerateMux + }; + } + + function makePassthruHandler(obj) { + // Handler copied from + // http://wiki.ecmascript.org/doku.php?id=harmony:proxies&s=proxy%20object#examplea_no-op_forwarding_proxy + return { + getOwnPropertyDescriptor: function(name) { + var desc = Object.getOwnPropertyDescriptor(obj, name); + + // a trapping proxy's properties must always be configurable + desc.configurable = true; + return desc; + }, + getPropertyDescriptor: function(name) { + var desc = getPropertyDescriptor(obj, name); + + // a trapping proxy's properties must always be configurable + desc.configurable = true; + return desc; + }, + getOwnPropertyNames: function() { + return Object.getOwnPropertyNames(obj); + }, + defineProperty: function(name, desc) { + Object.defineProperty(obj, name, desc); + }, + "delete": function(name) { return delete obj[name]; }, + fix: function() { + if (Object.isFrozen(obj)) { + return getOwnProperties(obj); + } + + // As long as obj is not frozen, the proxy won't allow itself to be fixed. + return undefined; // will cause a TypeError to be thrown + }, + + has: function(name) { return name in obj; }, + hasOwn: function(name) { return ({}).hasOwnProperty.call(obj, name); }, + get: function(receiver, name) { return obj[name]; }, + + // bad behavior when set fails in non-strict mode + set: function(receiver, name, val) { obj[name] = val; return true; }, + enumerate: function() { + var result = []; + for (name in obj) { result.push(name); }; + return result; + }, + keys: function() { return Object.keys(obj); } + }; + } + + // default function used when looking for a property in the global object + function noPropFound() { return undefined; } + + var hasOwnProperty = ({}).hasOwnProperty; + + function hasOwn(obj, name) { + return hasOwnProperty.call(obj, name); + } + + function StringMap(table, size) { + this.table = table || Object.create(null, {}); + this.size = size || 0; + } + + StringMap.create = function(table) { + var init = Object.create(null, {}); + var size = 0; + var names = Object.getOwnPropertyNames(table); + for (var i = 0, n = names.length; i < n; i++) { + var name = names[i]; + init[name] = table[name]; + size++; + } + return new StringMap(init, size); + }; + + StringMap.prototype = { + has: function(x) { return hasOwnProperty.call(this.table, x); }, + set: function(x, v) { + if (!hasOwnProperty.call(this.table, x)) + this.size++; + this.table[x] = v; + }, + get: function(x) { return this.table[x]; }, + getDef: function(x, thunk) { + if (!hasOwnProperty.call(this.table, x)) { + this.size++; + this.table[x] = thunk(); + } + return this.table[x]; + }, + forEach: function(f) { + var table = this.table; + for (var key in table) + f.call(this, key, table[key]); + }, + map: function(f) { + var table1 = this.table; + var table2 = Object.create(null, {}); + this.forEach(function(key, val) { + table2[key] = f.call(this, val, key); + }); + return new StringMap(table2, this.size); + }, + mapObject: function(f) { + var table1 = this.table; + var table2 = Object.create(null, {}); + this.forEach(function(key, val) { + table2[key] = f.call(this, val, key); + }); + return table2; + }, + toObject: function() { + return this.mapObject(function(val) { return val; }); + }, + choose: function() { + return Object.getOwnPropertyNames(this.table)[0]; + }, + remove: function(x) { + if (hasOwnProperty.call(this.table, x)) { + this.size--; + delete this.table[x]; + } + }, + copy: function() { + var table = Object.create(null, {}); + for (var key in this.table) + table[key] = this.table[key]; + return new StringMap(table, this.size); + }, + toString: function() { return "[object StringMap]" } + }; + + // an object-key table with poor asymptotics (replace with WeakMap when possible) + function ObjectMap(array) { + this.array = array || []; + } + + function searchMap(map, key, found, notFound) { + var a = map.array; + for (var i = 0, n = a.length; i < n; i++) { + var pair = a[i]; + if (pair.key === key) + return found(pair, i); + } + return notFound(); + } + + ObjectMap.prototype = { + has: function(x) { + return searchMap(this, x, function() { return true }, function() { return false }); + }, + set: function(x, v) { + var a = this.array; + searchMap(this, x, + function(pair) { pair.value = v }, + function() { a.push({ key: x, value: v }) }); + }, + get: function(x) { + return searchMap(this, x, + function(pair) { return pair.value }, + function() { return null }); + }, + getDef: function(x, thunk) { + var a = this.array; + return searchMap(this, x, + function(pair) { return pair.value }, + function() { + var v = thunk(); + a.push({ key: x, value: v }); + return v; + }); + }, + forEach: function(f) { + var a = this.array; + for (var i = 0, n = a.length; i < n; i++) { + var pair = a[i]; + f.call(this, pair.key, pair.value); + } + }, + choose: function() { + return this.array[0].key; + }, + get size() { + return this.array.length; + }, + remove: function(x) { + var a = this.array; + searchMap(this, x, + function(pair, i) { a.splice(i, 1) }, + function() { }); + }, + copy: function() { + return new ObjectMap(this.array.map(function(pair) { + return { key: pair.key, value: pair.value } + })); + }, + clear: function() { + this.array = []; + }, + toString: function() { return "[object ObjectMap]" } + }; + + // non-destructive stack + function Stack(elts) { + this.elts = elts || null; + } + + Stack.prototype = { + push: function(x) { + return new Stack({ top: x, rest: this.elts }); + }, + top: function() { + if (!this.elts) + throw new Error("empty stack"); + return this.elts.top; + }, + isEmpty: function() { + return this.top === null; + }, + find: function(test) { + for (var elts = this.elts; elts; elts = elts.rest) { + if (test(elts.top)) + return elts.top; + } + return null; + }, + has: function(x) { + return Boolean(this.find(function(elt) { return elt === x })); + }, + forEach: function(f) { + for (var elts = this.elts; elts; elts = elts.rest) { + f(elts.top); + } + } + }; + + return { + tokens: tokens, + whitespace: whitespace, + opTypeNames: opTypeNames, + keywords: keywords, + isStatementStartCode: isStatementStartCode, + tokenIds: tokenIds, + consts: consts, + assignOps: assignOps, + defineGetter: defineGetter, + defineGetterSetter: defineGetterSetter, + defineMemoGetter: defineMemoGetter, + defineProperty: defineProperty, + isNativeCode: isNativeCode, + mirrorHandler: mirrorHandler, + mixinHandler: mixinHandler, + whitelistHandler: whitelistHandler, + blacklistHandler: blacklistHandler, + makePassthruHandler: makePassthruHandler, + noPropFound: noPropFound, + StringMap: StringMap, + ObjectMap: ObjectMap, + Stack: Stack + }; +}()); diff --git a/node_modules/narcissus/lib/jsexec.js b/node_modules/narcissus/lib/jsexec.js new file mode 100644 index 00000000..ea1a7eb5 --- /dev/null +++ b/node_modules/narcissus/lib/jsexec.js @@ -0,0 +1,1484 @@ +/* -*- Mode: JS; tab-width: 4; indent-tabs-mode: nil; -*- + * vim: set sw=4 ts=4 et tw=78: +/* ***** BEGIN LICENSE BLOCK ***** + * + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Narcissus JavaScript engine. + * + * The Initial Developer of the Original Code is + * Brendan Eich . + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tom Austin + * Brendan Eich + * Shu-Yu Guo + * Dave Herman + * Dimitris Vardoulakis + * Patrick Walton + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Narcissus - JS implemented in JS. + * + * Execution of parse trees. + * + * Standard classes except for eval, Function, Array, and String are borrowed + * from the host JS environment. Function is metacircular. Array and String + * are reflected via wrapping the corresponding native constructor and adding + * an extra level of prototype-based delegation. + */ + +Narcissus.interpreter = (function() { + + var parser = Narcissus.parser; + var definitions = Narcissus.definitions; + var resolver = Narcissus.resolver; + var hostGlobal = Narcissus.hostGlobal; + + // Set constants in the local scope. + eval(definitions.consts); + + const StringMap = definitions.StringMap; + const ObjectMap = definitions.ObjectMap; + const StaticEnv = resolver.StaticEnv; + const Def = resolver.Def; + + const GLOBAL_CODE = 0, EVAL_CODE = 1, FUNCTION_CODE = 2, MODULE_CODE = 3; + + function ExecutionContext(type, version) { + this.type = type; + this.version = version; + // In Harmony, the global scope record is not exposed to the program. + if (type === GLOBAL_CODE && version === "harmony") { + this.scope = {object: globalScope, parent: null}; + this.thisObject = globalMirror; + } + } + + function isStackOverflow(e) { + var re = /InternalError: (script stack space quota is exhausted|too much recursion)/; + return re.test(e.toString()); + } + + // The underlying global object for narcissus. + var globalBase = { + // Value properties. + NaN: NaN, Infinity: Infinity, undefined: undefined, + + // Function properties. + eval: function eval(s) { + if (typeof s !== "string") + return s; + + var x = ExecutionContext.current; + var x2 = new ExecutionContext(EVAL_CODE, x.version); + x2.thisObject = x.thisObject; + x2.thisModule = x.thisModule; + x2.caller = x.caller; + x2.callee = x.callee; + x2.scope = x.version === "harmony" ? { object: new Object, parent: x.scope } : x.scope; + try { + var ast = parser.parse(s); + if (x.version === "harmony") { + resolver.resolve(ast, new StaticEnv(x.staticEnv)); + instantiateModules(ast, x2.scope); + } + x2.execute(ast); + return x2.result; + } catch (e if e instanceof SyntaxError || isStackOverflow(e)) { + /* + * If we get an internal error during parsing we need to reify + * the exception as a Narcissus THROW. + * + * See bug 152646. + */ + x.result = e; + throw THROW; + } + }, + + // Class constructors. Where ECMA-262 requires C.length === 1, we declare + // a dummy formal parameter. + Function: function Function(dummy) { + var p = "", b = "", n = arguments.length; + if (n) { + var m = n - 1; + if (m) { + p += arguments[0]; + for (var k = 1; k < m; k++) + p += "," + arguments[k]; + } + b += arguments[m]; + } + + // XXX We want to pass a good file and line to the tokenizer. + // Note the anonymous name to maintain parity with Spidermonkey. + var t = new parser.Tokenizer("anonymous(" + p + ") {" + b + "}"); + + // NB: Use the STATEMENT_FORM constant since we don't want to push this + // function onto the fake compilation context. + var f = parser.FunctionDefinition(t, null, false, parser.STATEMENT_FORM); + var s = {object: global, parent: null}; + return newFunction(f,{scope:s}); + }, + Array: function (dummy) { + // Array when called as a function acts as a constructor. + return Array.apply(this, arguments); + }, + String: function String(s) { + // Called as function or constructor: convert argument to string type. + s = arguments.length ? "" + s : ""; + if (this instanceof String) { + // Called as constructor: save the argument as the string value + // of this String object and return this object. + this.value = s; + return this; + } + return s; + }, + + // Don't want to proxy RegExp or some features won't work + RegExp: RegExp, + + // Extensions to ECMA. + load: function load(s) { + if (typeof s !== "string") + return s; + + evaluate(snarf(s), s, 1) + }, + version: function() { return ExecutionContext.current.version; }, + quit: function() { throw END; }, + assertEq: function() { + try { + return assertEq.apply(null, arguments); + } catch (e) { + ExecutionContext.current.result = e; + throw THROW; + } + } + }; + + function wrapNative(name, val) { + if (!definitions.isNativeCode(val)) + return val; + return Proxy.createFunction( + definitions.makePassthruHandler(val), + function() { return val.apply(hostGlobal, arguments); }, + function() { + var a = arguments; + switch (a.length) { + case 0: + return new val(); + case 1: + return new val(a[0]); + case 2: + return new val(a[0], a[1]); + case 3: + return new val(a[0], a[1], a[2]); + default: + var argStr = ""; + for (var i = 0; i < a.length; i++) + argStr += 'a[' + i + '],'; + return eval('new ' + name + '(' + argStr.slice(0,-1) + ');'); + } + }); + } + + var hostHandler = definitions.blacklistHandler(hostGlobal, { Narcissus: true }); + var hostHandlerGet = hostHandler.get; + hostHandler.get = function(receiver, name) { + return wrapNative(name, hostHandlerGet(receiver, name)); + }; + var hostProxy = Proxy.create(hostHandler); + + var globalStaticEnv; // global static scope + var moduleInstances = new ObjectMap(); // maps module instance objects -> module instances + var global = Object.create(hostProxy, {}); // exposed global object (legacy) + + // unexposed global scope record (Harmony) + var globalScope = Object.create(hostProxy, {}); + + // exposed global scope mirror (Harmony) + var globalMirror = Proxy.create(definitions.mirrorHandler(globalScope, true)); + + function resetEnvironment() { + ExecutionContext.current = new ExecutionContext(GLOBAL_CODE, Narcissus.options.version); + let names = Object.getOwnPropertyNames(global); + for (let i = 0, n = names.length; i < n; i++) { + delete global[names[i]]; + } + for (let key in globalScope) { + delete globalScope[key]; + } + moduleInstances.clear(); + globalStaticEnv = new StaticEnv(); + + let names = Object.getOwnPropertyNames(hostProxy); + for (let i = 0, n = names.length; i < n; i++) { + globalStaticEnv.bind(names[i], new Def()); + } + for (let key in globalBase) { + let val = globalBase[key]; + global[key] = val; + globalScope[key] = val; + // NB: this assumes globalBase never contains module or import bindings + globalStaticEnv.bind(key, new Def()); + } + } + resetEnvironment(); + + // Helper to avoid Object.prototype.hasOwnProperty polluting scope objects. + function hasDirectProperty(o, p) { + return Object.prototype.hasOwnProperty.call(o, p); + } + + // Reflect a host class into the target global environment by delegation. + function reflectClass(name, proto) { + var gctor = global[name]; + definitions.defineProperty(gctor, "prototype", proto, true, true, true); + definitions.defineProperty(proto, "constructor", gctor, false, false, true); + return proto; + } + + // Reflect Array -- note that all Array methods are generic. + reflectClass('Array', new Array); + + // Reflect String, overriding non-generic methods. + var gSp = reflectClass('String', new String); + gSp.toSource = function () { return this.value.toSource(); }; + gSp.toString = function () { return this.value; }; + gSp.valueOf = function () { return this.value; }; + global.String.fromCharCode = String.fromCharCode; + + ExecutionContext.current = null; + + ExecutionContext.prototype = { + caller: null, + callee: null, + scope: {object: global, parent: null}, + thisObject: global, + thisModule: null, + result: undefined, + target: null, + ecma3OnlyMode: false, + + // Execute a node in this execution context. + execute: function(n) { + var prev = ExecutionContext.current; + ExecutionContext.current = this; + try { + execute(n, this); + } catch (e if e === THROW) { + // Propagate the throw to the previous context if it exists. + if (prev) { + prev.result = this.result; + throw THROW; + } + // Otherwise reflect the throw into host JS. + throw this.result; + } finally { + ExecutionContext.current = prev; + } + } + }; + + function Reference(base, propertyName, node) { + this.base = base; + this.propertyName = propertyName; + this.node = node; + } + + Reference.prototype.toString = function () { return this.node.getSource(); } + + function getValue(v) { + if (v instanceof Reference) { + if (!v.base) { + throw new ReferenceError(v.propertyName + " is not defined", + v.node.filename, v.node.lineno); + } + return v.base[v.propertyName]; + } + return v; + } + + function putValue(v, w, vn) { + if (v instanceof Reference) + return (v.base || global)[v.propertyName] = w; + throw new ReferenceError("Invalid assignment left-hand side", + vn.filename, vn.lineno); + } + + function isPrimitive(v) { + var t = typeof v; + return (t === "object") ? v === null : t !== "function"; + } + + function isObject(v) { + var t = typeof v; + return (t === "object") ? v !== null : t === "function"; + } + + // If r instanceof Reference, v === getValue(r); else v === r. If passed, rn + // is the node whose execute result was r. + function toObject(v, r, rn) { + switch (typeof v) { + case "boolean": + return new global.Boolean(v); + case "number": + return new global.Number(v); + case "string": + return new global.String(v); + case "function": + return v; + case "object": + if (v !== null) + return v; + } + var message = r + " (type " + (typeof v) + ") has no properties"; + throw rn ? new TypeError(message, rn.filename, rn.lineno) + : new TypeError(message); + } + + // reifyModule :: (Module) -> module instance object + function reifyModule(mod) { + return mod.instance.proxy; + } + + function bindImports(impDecls, x) { + for (var i = 0; i < impDecls.length; i++) { + var list = impDecls[i].pathList; + for (var j = 0; j < list.length; j++) { + bindImport(list[j], x); + } + } + } + + function bindImport(decl, x) { + var t = x.scope.object; + var lhs = decl.children[0]; + var rhs = decl.children[1]; + var mod = lhs.denotedModule; + + function bind(importID, exportID) { + definitions.defineGetter(t, importID, function() { + var m = reifyModule(mod); + return m[exportID]; + }, true); + } + + if (rhs.type === IDENTIFIER) { + if (rhs.value === "*") { + mod.exports.forEach(function(exportID, exp) { + if (!mod.exportedModules.has(exportID)) + bind(exportID, exportID); + }); + } else { + bind(rhs.value, rhs.value); + } + return; + } + + for (var i = 0; i < rhs.children.length; i++) { + var pair = rhs.children[i]; + bind(pair.children[1].value, pair.children[0].value); + } + } + + function executeModule(n, x) { + var m = x.scope.object[n.name]; + var inst = moduleInstances.get(m); + var x2 = new ExecutionContext(MODULE_CODE, x.version); + x2.scope = inst.scope; + x2.thisObject = m; + x2.thisModule = m; + x2.execute(n.body); + return m; + } + + function execute(n, x) { + var a, c, f, i, j, r, s, t, u, v; + + switch (n.type) { + case MODULE: + if (n.body) + x.result = executeModule(n, x); + break; + + case IMPORT: + case EXPORT: + break; + + case FUNCTION: + if (n.functionForm !== parser.DECLARED_FORM) { + if (!n.name || n.functionForm === parser.STATEMENT_FORM) { + v = newFunction(n, x); + if (n.functionForm === parser.STATEMENT_FORM) + definitions.defineProperty(x.scope.object, n.name, v, true); + } else { + t = new Object; + x.scope = {object: t, parent: x.scope}; + try { + v = newFunction(n, x); + definitions.defineProperty(t, n.name, v, true, true); + } finally { + x.scope = x.scope.parent; + } + } + } + break; + + case SCRIPT: + t = x.scope.object; + n.modAssns.forEach(function(name, node) { + definitions.defineMemoGetter(t, name, function() { + return reifyModule(node.initializer.denotedModule); + }, true); + }); + bindImports(n.impDecls, x); + a = n.funDecls; + for (i = 0, j = a.length; i < j; i++) { + s = a[i].name; + f = newFunction(a[i], x); + // ECMA-262 says variable bindings created by `eval' are deleteable. + definitions.defineProperty(t, s, f, x.type !== EVAL_CODE); + } + a = n.varDecls; + var defineVar; + if (x.thisModule) { + defineVar = function(obj, prop) { + // start out as a getter/setter that throws on get + definitions.defineGetterSetter(obj, prop, function() { + throw new ReferenceError(prop + " is not initialized"); + }, function(val) { + // on first set, replace with ordinary property + definitions.defineProperty(obj, prop, val, false); + return val; + }, false); + }; + } else { + defineVar = function(obj, prop) { + // ECMA-262 says variable bindings created by `eval' are deleteable. + definitions.defineProperty(obj, prop, undefined, x.type !== EVAL_CODE, false); + }; + } + for (i = 0, j = a.length; i < j; i++) { + u = a[i]; + s = u.name; + if (u.readOnly && hasDirectProperty(t, s)) { + throw new TypeError("Redeclaration of const " + s, + u.filename, u.lineno); + } + if (u.readOnly || !hasDirectProperty(t, s)) { + // Does not correctly handle 'const x;' -- see bug 592335. + defineVar(t, s); + } + } + // FALL THROUGH + + case BLOCK: + c = n.children; + for (i = 0, j = c.length; i < j; i++) + execute(c[i], x); + break; + + case IMPORT: + case EXPORT: + break; + + case IF: + if (getValue(execute(n.condition, x))) + execute(n.thenPart, x); + else if (n.elsePart) + execute(n.elsePart, x); + break; + + case SWITCH: + s = getValue(execute(n.discriminant, x)); + a = n.cases; + var matchDefault = false; + switch_loop: + for (i = 0, j = a.length; ; i++) { + if (i === j) { + if (n.defaultIndex >= 0) { + i = n.defaultIndex - 1; // no case matched, do default + matchDefault = true; + continue; + } + break; // no default, exit switch_loop + } + t = a[i]; // next case (might be default!) + if (t.type === CASE) { + u = getValue(execute(t.caseLabel, x)); + } else { + if (!matchDefault) // not defaulting, skip for now + continue; + u = s; // force match to do default + } + if (u === s) { + for (;;) { // this loop exits switch_loop + if (t.statements.children.length) { + try { + execute(t.statements, x); + } catch (e if e === BREAK && x.target === n) { + break switch_loop; + } + } + if (++i === j) + break switch_loop; + t = a[i]; + } + // NOT REACHED + } + } + break; + + case FOR: + n.setup && getValue(execute(n.setup, x)); + // FALL THROUGH + case WHILE: + while (!n.condition || getValue(execute(n.condition, x))) { + try { + execute(n.body, x); + } catch (e if e === BREAK && x.target === n) { + break; + } catch (e if e === CONTINUE && x.target === n) { + // Must run the update expression. + } + n.update && getValue(execute(n.update, x)); + } + break; + + case FOR_IN: + u = n.varDecl; + if (u) + execute(u, x); + r = n.iterator; + s = execute(n.object, x); + v = getValue(s); + + // ECMA deviation to track extant browser JS implementation behavior. + t = ((v === null || v === undefined) && !x.ecma3OnlyMode) + ? v + : toObject(v, s, n.object); + a = []; + for (i in t) + a.push(i); + for (i = 0, j = a.length; i < j; i++) { + putValue(execute(r, x), a[i], r); + try { + execute(n.body, x); + } catch (e if e === BREAK && x.target === n) { + break; + } catch (e if e === CONTINUE && x.target === n) { + continue; + } + } + break; + + case DO: + do { + try { + execute(n.body, x); + } catch (e if e === BREAK && x.target === n) { + break; + } catch (e if e === CONTINUE && x.target === n) { + continue; + } + } while (getValue(execute(n.condition, x))); + break; + + case BREAK: + case CONTINUE: + x.target = n.target; + throw n.type; + + case TRY: + try { + execute(n.tryBlock, x); + } catch (e if e === THROW && (j = n.catchClauses.length)) { + e = x.result; + x.result = undefined; + for (i = 0; ; i++) { + if (i === j) { + x.result = e; + throw THROW; + } + t = n.catchClauses[i]; + x.scope = {object: {}, parent: x.scope}; + definitions.defineProperty(x.scope.object, t.varName, e, true); + try { + if (t.guard && !getValue(execute(t.guard, x))) + continue; + execute(t.block, x); + break; + } finally { + x.scope = x.scope.parent; + } + } + } finally { + if (n.finallyBlock) + execute(n.finallyBlock, x); + } + break; + + case THROW: + x.result = getValue(execute(n.exception, x)); + throw THROW; + + case RETURN: + // Check for returns with no return value + x.result = n.value ? getValue(execute(n.value, x)) : undefined; + throw RETURN; + + case WITH: + r = execute(n.object, x); + t = toObject(getValue(r), r, n.object); + x.scope = {object: t, parent: x.scope}; + try { + execute(n.body, x); + } finally { + x.scope = x.scope.parent; + } + break; + + case VAR: + case CONST: + c = n.children; + for (i = 0, j = c.length; i < j; i++) { + u = c[i].initializer; + if (!u) + continue; + t = c[i].name; + for (s = x.scope; s; s = s.parent) { + if (hasDirectProperty(s.object, t)) + break; + } + u = getValue(execute(u, x)); + if (n.type === CONST) + definitions.defineProperty(s.object, t, u, x.type !== EVAL_CODE, true); + else + s.object[t] = u; + } + break; + + case DEBUGGER: + throw "NYI: " + definitions.tokens[n.type]; + + case SEMICOLON: + if (n.expression) + x.result = getValue(execute(n.expression, x)); + break; + + case LABEL: + try { + execute(n.statement, x); + } catch (e if e === BREAK && x.target === n.target) { + } + break; + + case COMMA: + c = n.children; + for (i = 0, j = c.length; i < j; i++) + v = getValue(execute(c[i], x)); + break; + + case ASSIGN: + c = n.children; + r = execute(c[0], x); + t = n.assignOp; + if (t) + u = getValue(r); + v = getValue(execute(c[1], x)); + if (t) { + switch (t) { + case BITWISE_OR: v = u | v; break; + case BITWISE_XOR: v = u ^ v; break; + case BITWISE_AND: v = u & v; break; + case LSH: v = u << v; break; + case RSH: v = u >> v; break; + case URSH: v = u >>> v; break; + case PLUS: v = u + v; break; + case MINUS: v = u - v; break; + case MUL: v = u * v; break; + case DIV: v = u / v; break; + case MOD: v = u % v; break; + } + } + putValue(r, v, c[0]); + break; + + case HOOK: + c = n.children; + v = getValue(execute(c[0], x)) ? getValue(execute(c[1], x)) + : getValue(execute(c[2], x)); + break; + + case OR: + c = n.children; + v = getValue(execute(c[0], x)) || getValue(execute(c[1], x)); + break; + + case AND: + c = n.children; + v = getValue(execute(c[0], x)) && getValue(execute(c[1], x)); + break; + + case BITWISE_OR: + c = n.children; + v = getValue(execute(c[0], x)) | getValue(execute(c[1], x)); + break; + + case BITWISE_XOR: + c = n.children; + v = getValue(execute(c[0], x)) ^ getValue(execute(c[1], x)); + break; + + case BITWISE_AND: + c = n.children; + v = getValue(execute(c[0], x)) & getValue(execute(c[1], x)); + break; + + case EQ: + c = n.children; + v = getValue(execute(c[0], x)) == getValue(execute(c[1], x)); + break; + + case NE: + c = n.children; + v = getValue(execute(c[0], x)) != getValue(execute(c[1], x)); + break; + + case STRICT_EQ: + c = n.children; + v = getValue(execute(c[0], x)) === getValue(execute(c[1], x)); + break; + + case STRICT_NE: + c = n.children; + v = getValue(execute(c[0], x)) !== getValue(execute(c[1], x)); + break; + + case LT: + c = n.children; + v = getValue(execute(c[0], x)) < getValue(execute(c[1], x)); + break; + + case LE: + c = n.children; + v = getValue(execute(c[0], x)) <= getValue(execute(c[1], x)); + break; + + case GE: + c = n.children; + v = getValue(execute(c[0], x)) >= getValue(execute(c[1], x)); + break; + + case GT: + c = n.children; + v = getValue(execute(c[0], x)) > getValue(execute(c[1], x)); + break; + + case IN: + c = n.children; + v = getValue(execute(c[0], x)) in getValue(execute(c[1], x)); + break; + + case INSTANCEOF: + c = n.children; + t = getValue(execute(c[0], x)); + u = getValue(execute(c[1], x)); + if (isObject(u) && typeof u.__hasInstance__ === "function") + v = u.__hasInstance__(t); + else + v = t instanceof u; + break; + + case LSH: + c = n.children; + v = getValue(execute(c[0], x)) << getValue(execute(c[1], x)); + break; + + case RSH: + c = n.children; + v = getValue(execute(c[0], x)) >> getValue(execute(c[1], x)); + break; + + case URSH: + c = n.children; + v = getValue(execute(c[0], x)) >>> getValue(execute(c[1], x)); + break; + + case PLUS: + c = n.children; + v = getValue(execute(c[0], x)) + getValue(execute(c[1], x)); + break; + + case MINUS: + c = n.children; + v = getValue(execute(c[0], x)) - getValue(execute(c[1], x)); + break; + + case MUL: + c = n.children; + v = getValue(execute(c[0], x)) * getValue(execute(c[1], x)); + break; + + case DIV: + c = n.children; + v = getValue(execute(c[0], x)) / getValue(execute(c[1], x)); + break; + + case MOD: + c = n.children; + v = getValue(execute(c[0], x)) % getValue(execute(c[1], x)); + break; + + case DELETE: + t = execute(n.children[0], x); + v = !(t instanceof Reference) || delete t.base[t.propertyName]; + break; + + case VOID: + getValue(execute(n.children[0], x)); + break; + + case TYPEOF: + t = execute(n.children[0], x); + if (t instanceof Reference) + t = t.base ? t.base[t.propertyName] : undefined; + v = typeof t; + break; + + case NOT: + v = !getValue(execute(n.children[0], x)); + break; + + case BITWISE_NOT: + v = ~getValue(execute(n.children[0], x)); + break; + + case UNARY_PLUS: + v = +getValue(execute(n.children[0], x)); + break; + + case UNARY_MINUS: + v = -getValue(execute(n.children[0], x)); + break; + + case INCREMENT: + case DECREMENT: + t = execute(n.children[0], x); + u = Number(getValue(t)); + if (n.postfix) + v = u; + putValue(t, (n.type === INCREMENT) ? ++u : --u, n.children[0]); + if (!n.postfix) + v = u; + break; + + case DOT: + c = n.children; + r = execute(c[0], x); + t = getValue(r); + u = c[1].value; + v = new Reference(toObject(t, r, c[0]), u, n); + break; + + case INDEX: + c = n.children; + r = execute(c[0], x); + t = getValue(r); + u = getValue(execute(c[1], x)); + v = new Reference(toObject(t, r, c[0]), String(u), n); + break; + + case LIST: + // Curse ECMA for specifying that arguments is not an Array object! + v = {}; + c = n.children; + for (i = 0, j = c.length; i < j; i++) { + u = getValue(execute(c[i], x)); + definitions.defineProperty(v, i, u, false, false, true); + } + definitions.defineProperty(v, "length", i, false, false, true); + break; + + case CALL: + c = n.children; + r = execute(c[0], x); + a = execute(c[1], x); + f = getValue(r); + x.staticEnv = n.staticEnv; + if (isPrimitive(f) || typeof f.__call__ !== "function") { + throw new TypeError(r + " is not callable", c[0].filename, c[0].lineno); + } + t = (r instanceof Reference) ? r.base : null; + if (t instanceof Activation) + t = null; + v = f.__call__(t, a, x); + break; + + case NEW: + case NEW_WITH_ARGS: + c = n.children; + r = execute(c[0], x); + f = getValue(r); + if (n.type === NEW) { + a = {}; + definitions.defineProperty(a, "length", 0, false, false, true); + } else { + a = execute(c[1], x); + } + if (isPrimitive(f) || typeof f.__construct__ !== "function") { + throw new TypeError(r + " is not a constructor", c[0].filename, c[0].lineno); + } + v = f.__construct__(a, x); + break; + + case ARRAY_INIT: + v = []; + c = n.children; + for (i = 0, j = c.length; i < j; i++) { + if (c[i]) + v[i] = getValue(execute(c[i], x)); + } + v.length = j; + break; + + case OBJECT_INIT: + v = {}; + c = n.children; + for (i = 0, j = c.length; i < j; i++) { + t = c[i]; + if (t.type === PROPERTY_INIT) { + let c2 = t.children; + v[c2[0].value] = getValue(execute(c2[1], x)); + } else { + f = newFunction(t, x); + u = (t.type === GETTER) ? '__defineGetter__' + : '__defineSetter__'; + v[u](t.name, thunk(f, x)); + } + } + break; + + case NULL: + v = null; + break; + + case THIS: + v = x.thisObject; + break; + + case TRUE: + v = true; + break; + + case FALSE: + v = false; + break; + + case IDENTIFIER: + for (s = x.scope; s; s = s.parent) { + if (n.value in s.object) + break; + } + v = new Reference(s && s.object, n.value, n); + break; + + case NUMBER: + case STRING: + case REGEXP: + v = n.value; + break; + + case GROUP: + v = execute(n.children[0], x); + break; + + default: + throw "PANIC: unknown operation " + n.type + ": " + uneval(n); + } + + return v; + } + + function Activation(f, a) { + for (var i = 0, j = f.params.length; i < j; i++) + definitions.defineProperty(this, f.params[i], a[i], true); + definitions.defineProperty(this, "arguments", a, true); + } + + // Null Activation.prototype's proto slot so that Object.prototype.* does not + // pollute the scope of heavyweight functions. Also delete its 'constructor' + // property so that it doesn't pollute function scopes. + + Activation.prototype.__proto__ = null; + delete Activation.prototype.constructor; + + function FunctionObject(node, scope) { + this.node = node; + this.scope = scope; + definitions.defineProperty(this, "length", node.params.length, true, true, true); + var proto = {}; + definitions.defineProperty(this, "prototype", proto, true); + definitions.defineProperty(proto, "constructor", this, false, false, true); + } + + /* + * ModuleInstance :: (Module, scope) -> ModuleInstance + * + * Dynamic semantic representation of a module. + */ + function ModuleInstance(mod, scope) { + this.module = mod; + this.scope = scope; + } + + /* + * newModule :: (Module, scope) -> module instance object + * + * Instantiates a module node, producing a module instance object. + */ + function newModule(mod, scope) { + var exports = mod.exports; + + // the module instance + mod.instance = new ModuleInstance(mod, {object: new Object, parent: scope}); + + function keys() { + var result = []; + exports.forEach(function(name, exp) { + result.push(name); + }); + return result; + } + + function getExportDescriptor(name) { + if (exports.has(name)) { + var exp = exports.get(name); + var inst = exp.resolved.module.instance; + + return { + value: inst.scope.object[exp.resolved.internalID], + writable: false, + enumerable: true, + configurable: true + }; + } + + throw new ReferenceError("no such export: " + name); + } + + function getExportValue(receiver, name) { + return getExportDescriptor(name).value; + } + + function hasExport(name) { + return exports.has(name); + } + + function refuse() { } + + // the module instance proxy + var instObj = Proxy.create({ + getOwnPropertyDescriptor: getExportDescriptor, + getPropertyDescriptor: getExportDescriptor, + getOwnPropertyNames: keys, + defineProperty: refuse, + "delete": refuse, + fix: refuse, + has: hasExport, + hasOwn: hasExport, + get: getExportValue, + set: refuse, + enumerate: keys, + keys: keys + }); + + // associate the instance with the instance proxy + moduleInstances.set(instObj, mod.instance); + mod.instance.proxy = instObj; + + return instObj; + } + + function instantiateModules(n, scope) { + n.modDefns.forEach(function(name, defn) { + var m = defn.module; + var instObj = newModule(m, scope); + var inst = moduleInstances.get(instObj); + definitions.defineProperty(scope.object, name, instObj, true, true); + instantiateModules(m.node.body, inst.scope); + }); + } + + function getPropertyDescriptor(obj, name) { + while (obj) { + if (({}).hasOwnProperty.call(obj, name)) + return Object.getOwnPropertyDescriptor(obj, name); + obj = Object.getPrototypeOf(obj); + } + } + + function getOwnProperties(obj) { + var map = {}; + for (var name in Object.getOwnPropertyNames(obj)) + map[name] = Object.getOwnPropertyDescriptor(obj, name); + return map; + } + + // Returns a new function wrapped with a Proxy. + function newFunction(n, x) { + var fobj = new FunctionObject(n, x.scope); + var handler = definitions.makePassthruHandler(fobj); + var p = Proxy.createFunction(handler, + function() { return fobj.__call__(this, arguments, x); }, + function() { return fobj.__construct__(arguments, x); }); + return p; + } + + var FOp = FunctionObject.prototype = { + + // Internal methods. + __call__: function (t, a, x) { + var x2 = new ExecutionContext(FUNCTION_CODE, x.version); + x2.thisObject = t || global; + x2.thisModule = null; + x2.caller = x; + x2.callee = this; + definitions.defineProperty(a, "callee", this, false, false, true); + var f = this.node; + x2.scope = {object: new Activation(f, a), parent: this.scope}; + + try { + x2.execute(f.body); + } catch (e if e === RETURN) { + return x2.result; + } + return undefined; + }, + + __construct__: function (a, x) { + var o = new Object; + var p = this.prototype; + if (isObject(p)) + o.__proto__ = p; + // else o.__proto__ defaulted to Object.prototype + + var v = this.__call__(o, a, x); + if (isObject(v)) + return v; + return o; + }, + + __hasInstance__: function (v) { + if (isPrimitive(v)) + return false; + var p = this.prototype; + if (isPrimitive(p)) { + throw new TypeError("'prototype' property is not an object", + this.node.filename, this.node.lineno); + } + var o; + while ((o = v.__proto__)) { + if (o === p) + return true; + v = o; + } + return false; + }, + + // Standard methods. + toString: function () { + return this.node.getSource(); + }, + + apply: function (t, a) { + // Curse ECMA again! + if (typeof this.__call__ !== "function") { + throw new TypeError("Function.prototype.apply called on" + + " uncallable object"); + } + + if (t === undefined || t === null) + t = global; + else if (typeof t !== "object") + t = toObject(t, t); + + if (a === undefined || a === null) { + a = {}; + definitions.defineProperty(a, "length", 0, false, false, true); + } else if (a instanceof Array) { + var v = {}; + for (var i = 0, j = a.length; i < j; i++) + definitions.defineProperty(v, i, a[i], false, false, true); + definitions.defineProperty(v, "length", i, false, false, true); + a = v; + } else if (!(a instanceof Object)) { + // XXX check for a non-arguments object + throw new TypeError("Second argument to Function.prototype.apply" + + " must be an array or arguments object", + this.node.filename, this.node.lineno); + } + + return this.__call__(t, a, ExecutionContext.current); + }, + + call: function (t) { + // Curse ECMA a third time! + var a = Array.prototype.splice.call(arguments, 1); + return this.apply(t, a); + } + }; + + // Connect Function.prototype and Function.prototype.constructor in global. + reflectClass('Function', FOp); + + // Help native and host-scripted functions be like FunctionObjects. + var Fp = Function.prototype; + var REp = RegExp.prototype; + + if (!('__call__' in Fp)) { + definitions.defineProperty(Fp, "__call__", + function (t, a, x) { + // Curse ECMA yet again! + a = Array.prototype.splice.call(a, 0, a.length); + return this.apply(t, a); + }, true, true, true); + definitions.defineProperty(REp, "__call__", + function (t, a, x) { + a = Array.prototype.splice.call(a, 0, a.length); + return this.exec.apply(this, a); + }, true, true, true); + definitions.defineProperty(Fp, "__construct__", + function (a, x) { + a = Array.prototype.splice.call(a, 0, a.length); + switch (a.length) { + case 0: + return new this(); + case 1: + return new this(a[0]); + case 2: + return new this(a[0], a[1]); + case 3: + return new this(a[0], a[1], a[2]); + default: + var argStr = ""; + for (var i=0; i@"); + line = line.replace(/@(.*\/|\\)?([^\/\\]+:[0-9]+)/, " at $2"); + print(" in " + line); + } + } + } + + // A read-eval-print-loop that roughly tracks the behavior of the js shell. + function repl() { + + // Display a value similarly to the js shell. + function display(x) { + if (typeof x === "object") { + // At the js shell, objects with no |toSource| don't print. + if (x !== null && "toSource" in x) { + try { + print(x.toSource()); + } catch (e) { + } + } else { + print("null"); + } + } else if (typeof x === "string") { + print(uneval(x)); + } else if (typeof x !== "undefined") { + // Since x must be primitive, String can't throw. + print(String(x)); + } + } + + // String conversion that never throws. + function string(x) { + try { + return String(x); + } catch (e) { + return "unknown (can't convert to string)"; + } + } + + const BREAK_INTERACTION = {}; + + // isCommand :: (string) -> boolean + function isCommand(line) { + switch (line.trim()) { + case ".help": + print(".begin Begin multiline input mode."); + print(".break Sometimes you get stuck in a place you can't get out... This will get you out."); + print(".clear Break, and also clear the global environment."); + print(".end End multiline input mode."); + print(".exit Exit the prompt."); + print(".help Show repl options."); + return true; + + case ".clear": + resetEnvironment(); + // FALL THROUGH + + case ".break": + throw BREAK_INTERACTION; + + case ".exit": + throw END; + } + return false; + } + + var x = new ExecutionContext(GLOBAL_CODE, Narcissus.options.version); + + // Line number in/out parameter to parser.parseStdin. + var ln = {value: 0}; + + ExecutionContext.current = x; + for (;;) { + x.result = undefined; + putstr("njs> "); + var src = readline(); + + // If readline receives EOF it returns null. + if (src === null) { + print(""); + break; + } + ++ln.value; + + try { + var ast = parser.parseStdin(src, ln, "... ", isCommand); + if (x.version === "harmony") { + resolveGlobal(ast); + instantiateModules(ast, x.scope); + } + execute(ast, x); + display(x.result); + } catch (e if e === THROW) { + print("uncaught exception: " + string(x.result)); + } catch (e if e === END) { + break; + } catch (e if e === BREAK_INTERACTION) { + continue; + } catch (e if e instanceof SyntaxError) { + const PREFIX = (e.filename || "stdin") + ":" + e.lineNumber + ": "; + print(PREFIX + e.toString()); + print(PREFIX + e.source); + print(PREFIX + ".".repeat(e.cursor) + "^"); + } catch (e if e instanceof Error) { + print((e.filename || "stdin") + ":" + e.lineNumber + ": " + e.toString()); + if (e.stack) + printStackTrace(e.stack); + } catch (e) { + print("unexpected Narcissus exception (" + e + ")"); + throw e; + } + } + ExecutionContext.current = null; + } + + function test(thunk) { + try { + thunk(); + } catch (e) { + print(e.fileName + ":" + e.lineNumber + ": " + e.name + ": " + e.message); + printStackTrace(e.stack); + return false; + } + return true; + } + + return { + // resetEnvironment wipes any properties added externally to global, + // but properties added to globalBase will persist. + global: global, + globalBase: globalBase, + resetEnvironment: resetEnvironment, + evaluate: evaluate, + repl: repl, + test: test + }; + +}()); diff --git a/node_modules/narcissus/lib/jslex.js b/node_modules/narcissus/lib/jslex.js new file mode 100644 index 00000000..ae723587 --- /dev/null +++ b/node_modules/narcissus/lib/jslex.js @@ -0,0 +1,508 @@ +/* vim: set sw=4 ts=4 et tw=78: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Narcissus JavaScript engine. + * + * The Initial Developer of the Original Code is + * Brendan Eich . + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tom Austin + * Brendan Eich + * Shu-Yu Guo + * Dave Herman + * Dimitris Vardoulakis + * Patrick Walton + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Narcissus - JS implemented in JS. + * + * Lexical scanner. + */ + +Narcissus.lexer = (function() { + + var definitions = Narcissus.definitions; + + // Set constants in the local scope. + eval(definitions.consts); + + // Build up a trie of operator tokens. + var opTokens = {}; + for (var op in definitions.opTypeNames) { + if (op === '\n' || op === '.') + continue; + + var node = opTokens; + for (var i = 0; i < op.length; i++) { + var ch = op[i]; + if (!(ch in node)) + node[ch] = {}; + node = node[ch]; + node.op = op; + } + } + + /* + * Tokenizer :: (source, filename, line number) -> Tokenizer + */ + function Tokenizer(s, f, l) { + this.cursor = 0; + this.source = String(s); + this.tokens = []; + this.tokenIndex = 0; + this.lookahead = 0; + this.scanNewlines = false; + this.unexpectedEOF = false; + this.filename = f || ""; + this.lineno = l || 1; + this.jsdocs = []; + } + + Tokenizer.prototype = { + get done() { + // We need to set scanOperand to true here because the first thing + // might be a regexp. + return this.peek(true) === END; + }, + + get token() { + return this.tokens[this.tokenIndex]; + }, + + match: function (tt, scanOperand) { + return this.get(scanOperand) === tt || this.unget(); + }, + + mustMatch: function (tt) { + if (!this.match(tt)) { + throw this.newSyntaxError("Missing " + + definitions.tokens[tt].toLowerCase()); + } + return this.token; + }, + + peek: function (scanOperand) { + var tt, next; + if (this.lookahead) { + next = this.tokens[(this.tokenIndex + this.lookahead) & 3]; + tt = (this.scanNewlines && next.lineno !== this.lineno) + ? NEWLINE + : next.type; + } else { + tt = this.get(scanOperand); + this.unget(); + } + return tt; + }, + + peekOnSameLine: function (scanOperand) { + this.scanNewlines = true; + var tt = this.peek(scanOperand); + this.scanNewlines = false; + return tt; + }, + + // Eat comments and whitespace. + skip: function () { + var input = this.source, + jsdocComment = null; + for (;;) { + var ch = input[this.cursor++]; + var next = input[this.cursor]; + // handle \r, \r\n and (always preferable) \n + if (ch === '\r') { + // if the next character is \n, we don't care about this at all + if (next === '\n') continue; + + // otherwise, we want to consider this as a newline + ch = '\n'; + } + + if (ch === '\n' && !this.scanNewlines) { + this.lineno++; + } else if (ch === '/' && next === '*') { + this.cursor++; + if (input[this.cursor] === '*') { // like /** + this.cursor++; + jsdocComment = ''; + } + for (;;) { + ch = input[this.cursor++]; + if (ch === undefined) + throw this.newSyntaxError("Unterminated comment"); + + if (ch === '*') { + next = input[this.cursor]; + if (next === '/') { + if (jsdocComment) this.jsdocs.push(jsdocComment); + jsdocComment = null; + + this.cursor++; + if (typeof input[this.cursor+1] === 'undefined') { // eof + if (typeof this.onJsDoc === 'function') { + while(this.jsdocs.length) { + this.onJsDoc(this.jsdocs.shift()); + } + } + } + break; + } + } else if (ch === '\n') { + this.lineno++; + } + if (typeof jsdocComment === 'string') { jsdocComment += ch; } + } + } else if (ch === '/' && next === '/') { + this.cursor++; + for (;;) { + ch = input[this.cursor++]; + next = input[this.cursor]; + if (ch === undefined) + return; + + if (ch === '\r') { + // check for \r\n + if (next !== '\n') ch = '\n'; + } + + if (ch === '\n') { + if (this.scanNewlines) { + this.cursor--; + } else { + this.lineno++; + } + break; + } + } + } else if (!(ch in definitions.whitespace)) { + this.cursor--; + return; + } + } + }, + + // Lex the exponential part of a number, if present. Return true iff an + // exponential part was found. + lexExponent: function() { + var input = this.source; + var next = input[this.cursor]; + if (next === 'e' || next === 'E') { + this.cursor++; + ch = input[this.cursor++]; + if (ch === '+' || ch === '-') + ch = input[this.cursor++]; + + if (ch < '0' || ch > '9') + throw this.newSyntaxError("Missing exponent"); + + do { + ch = input[this.cursor++]; + } while (ch >= '0' && ch <= '9'); + this.cursor--; + + return true; + } + + return false; + }, + + lexZeroNumber: function (ch) { + var token = this.token, input = this.source; + token.type = NUMBER; + + ch = input[this.cursor++]; + if (ch === '.') { + do { + ch = input[this.cursor++]; + } while (ch >= '0' && ch <= '9'); + this.cursor--; + + this.lexExponent(); + token.value = parseFloat(token.start, this.cursor); + } else if (ch === 'x' || ch === 'X') { + do { + ch = input[this.cursor++]; + } while ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || + (ch >= 'A' && ch <= 'F')); + this.cursor--; + + token.value = parseInt(input.substring(token.start, this.cursor)); + } else if (ch >= '0' && ch <= '7') { + do { + ch = input[this.cursor++]; + } while (ch >= '0' && ch <= '7'); + this.cursor--; + + token.value = parseInt(input.substring(token.start, this.cursor)); + } else { + this.cursor--; + this.lexExponent(); // 0E1, &c. + token.value = 0; + } + }, + + lexNumber: function (ch) { + var token = this.token, input = this.source; + token.type = NUMBER; + + var floating = false; + do { + ch = input[this.cursor++]; + if (ch === '.' && !floating) { + floating = true; + ch = input[this.cursor++]; + } + } while (ch >= '0' && ch <= '9'); + + this.cursor--; + + var exponent = this.lexExponent(); + floating = floating || exponent; + + var str = input.substring(token.start, this.cursor); + token.value = floating ? parseFloat(str) : parseInt(str); + }, + + lexDot: function (ch) { + var token = this.token, input = this.source; + var next = input[this.cursor]; + if (next >= '0' && next <= '9') { + do { + ch = input[this.cursor++]; + } while (ch >= '0' && ch <= '9'); + this.cursor--; + + this.lexExponent(); + + token.type = NUMBER; + token.value = parseFloat(token.start, this.cursor); + } else { + token.type = DOT; + token.assignOp = null; + token.value = '.'; + } + }, + + lexString: function (ch) { + var token = this.token, input = this.source; + token.type = STRING; + + var hasEscapes = false; + var delim = ch; + while ((ch = input[this.cursor++]) !== delim) { + if (this.cursor == input.length) + throw this.newSyntaxError("Unterminated string literal"); + if (ch === '\\') { + hasEscapes = true; + if (++this.cursor == input.length) + throw this.newSyntaxError("Unterminated string literal"); + } + } + + token.value = hasEscapes + ? eval(input.substring(token.start, this.cursor)) + : input.substring(token.start + 1, this.cursor - 1); + }, + + lexRegExp: function (ch) { + var token = this.token, input = this.source; + token.type = REGEXP; + + do { + ch = input[this.cursor++]; + if (ch === '\\') { + this.cursor++; + } else if (ch === '[') { + do { + if (ch === undefined) + throw this.newSyntaxError("Unterminated character class"); + + if (ch === '\\') + this.cursor++; + + ch = input[this.cursor++]; + } while (ch !== ']'); + } else if (ch === undefined) { + throw this.newSyntaxError("Unterminated regex"); + } + } while (ch !== '/'); + + do { + ch = input[this.cursor++]; + } while (ch >= 'a' && ch <= 'z'); + + this.cursor--; + + token.value = eval(input.substring(token.start, this.cursor)); + }, + + lexOp: function (ch) { + var token = this.token, input = this.source; + + // A bit ugly, but it seems wasteful to write a trie lookup routine + // for only 3 characters... + var node = opTokens[ch]; + var next = input[this.cursor]; + if (next in node) { + node = node[next]; + this.cursor++; + next = input[this.cursor]; + if (next in node) { + node = node[next]; + this.cursor++; + next = input[this.cursor]; + } + } + + var op = node.op; + if (definitions.assignOps[op] && input[this.cursor] === '=') { + this.cursor++; + token.type = ASSIGN; + token.assignOp = definitions.tokenIds[definitions.opTypeNames[op]]; + op += '='; + } else { + token.type = definitions.tokenIds[definitions.opTypeNames[op]]; + token.assignOp = null; + } + + token.value = op; + }, + + // FIXME: Unicode escape sequences + // FIXME: Unicode identifiers + lexIdent: function (ch) { + var token = this.token, input = this.source; + + do { + ch = input[this.cursor++]; + } while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || ch === '$' || ch === '_'); + + this.cursor--; // Put the non-word character back. + + var id = input.substring(token.start, this.cursor); + token.type = definitions.keywords[id] || IDENTIFIER; + token.value = id; + }, + + /* + * Tokenizer.get :: void -> token type + * + * Consume input *only* if there is no lookahead. + * Dispatch to the appropriate lexing function depending on the input. + */ + get: function (scanOperand) { + var token; + while (this.lookahead) { + --this.lookahead; + this.tokenIndex = (this.tokenIndex + 1) & 3; + token = this.tokens[this.tokenIndex]; + if (token.type !== NEWLINE || this.scanNewlines) + return token.type; + } + + this.skip(); + + this.tokenIndex = (this.tokenIndex + 1) & 3; + token = this.tokens[this.tokenIndex]; + if (!token) + this.tokens[this.tokenIndex] = token = {}; + if (this.jsdocs && this.jsdocs.length) { + while (this.jsdocs.length > 1) { // orphaned jsdocComments have no code token + if (typeof this.onJsDoc === 'function' && this.jsdocs.length) { + this.onJsDoc(this.jsdocs.shift()); + } + else { // discard? + this.jsdocs.shift(); + } + } + token.jsdoc = this.jsdocs.pop(); + } + + var input = this.source; + if (this.cursor >= input.length) + return token.type = END; + + token.start = this.cursor; + token.lineno = this.lineno; + + var ch = input[this.cursor++]; + if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch === '$' || ch === '_') { + this.lexIdent(ch); + } else if (scanOperand && ch === '/') { + this.lexRegExp(ch); + } else if (ch in opTokens) { + this.lexOp(ch); + } else if (ch === '.') { + this.lexDot(ch); + } else if (ch >= '1' && ch <= '9') { + this.lexNumber(ch); + } else if (ch === '0') { + this.lexZeroNumber(ch); + } else if (ch === '"' || ch === "'") { + this.lexString(ch); + } else if (this.scanNewlines && (ch === '\n' || ch === '\r')) { + // if this was a \r, look for \r\n + if (ch === '\r' && input[this.cursor] === '\n') this.cursor++; + token.type = NEWLINE; + token.value = '\n'; + this.lineno++; + } else { + throw this.newSyntaxError("Illegal token"); + } + + token.end = this.cursor; + return token.type; + }, + + /* + * Tokenizer.unget :: void -> undefined + * + * Match depends on unget returning undefined. + */ + unget: function () { + if (++this.lookahead === 4) throw "PANIC: too much lookahead!"; + this.tokenIndex = (this.tokenIndex - 1) & 3; + }, + + newSyntaxError: function (m) { + var e = new SyntaxError(m, this.filename, this.lineno); + e.source = this.source; + e.cursor = this.lookahead + ? this.tokens[(this.tokenIndex + this.lookahead) & 3].start + : this.cursor; + return e; + }, + }; + + return { Tokenizer: Tokenizer }; + +}()); diff --git a/node_modules/narcissus/lib/jsparse.js b/node_modules/narcissus/lib/jsparse.js new file mode 100644 index 00000000..5961b720 --- /dev/null +++ b/node_modules/narcissus/lib/jsparse.js @@ -0,0 +1,1813 @@ +/* -*- Mode: JS; tab-width: 4; indent-tabs-mode: nil; -*- + * vim: set sw=4 ts=4 et tw=78: + * ***** BEGIN LICENSE BLOCK ***** + * + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Narcissus JavaScript engine. + * + * The Initial Developer of the Original Code is + * Brendan Eich . + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tom Austin + * Brendan Eich + * Shu-Yu Guo + * Dave Herman + * Dimitris Vardoulakis + * Patrick Walton + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Narcissus - JS implemented in JS. + * + * Parser. + */ + +Narcissus.parser = (function() { + + var lexer = Narcissus.lexer; + var definitions = Narcissus.definitions; + + const StringMap = definitions.StringMap; + const Stack = definitions.Stack; + + // Set constants in the local scope. + eval(definitions.consts); + + // Banned statement types by language version. + const blackLists = { 185: {}, harmony: {} }; + blackLists[185][IMPORT] = true; + blackLists[185][EXPORT] = true; + blackLists[185][MODULE] = true; + blackLists.harmony[WITH] = true; + + /* + * pushDestructuringVarDecls :: (node, hoisting node) -> void + * + * Recursively add all destructured declarations to varDecls. + */ + function pushDestructuringVarDecls(n, s) { + for (var i in n) { + var sub = n[i]; + if (sub.type === IDENTIFIER) { + s.varDecls.push(sub); + } else { + pushDestructuringVarDecls(sub, s); + } + } + } + + function StaticContext(parentScript, parentBlock, inModule, inFunction) { + this.parentScript = parentScript; + this.parentBlock = parentBlock || parentScript; + this.inModule = inModule || false; + this.inFunction = inFunction || false; + this.inForLoopInit = false; + this.topLevel = true; + this.allLabels = new Stack(); + this.currentLabels = new Stack(); + this.labeledTargets = new Stack(); + this.defaultLoopTarget = null; + this.defaultTarget = null; + this.blackList = blackLists[Narcissus.options.version]; + Narcissus.options.ecma3OnlyMode && (this.ecma3OnlyMode = true); + Narcissus.options.parenFreeMode && (this.parenFreeMode = true); + } + + StaticContext.prototype = { + ecma3OnlyMode: false, + parenFreeMode: false, + // non-destructive update via prototype extension + update: function(ext) { + var desc = {}; + for (var key in ext) { + desc[key] = { + value: ext[key], + writable: true, + enumerable: true, + configurable: true + } + } + return Object.create(this, desc); + }, + pushLabel: function(label) { + return this.update({ currentLabels: this.currentLabels.push(label), + allLabels: this.allLabels.push(label) }); + }, + pushTarget: function(target) { + var isDefaultLoopTarget = target.isLoop; + var isDefaultTarget = isDefaultLoopTarget || target.type === SWITCH; + + if (this.currentLabels.isEmpty()) { + if (isDefaultLoopTarget) this.update({ defaultLoopTarget: target }); + if (isDefaultTarget) this.update({ defaultTarget: target }); + return this; + } + + target.labels = new StringMap(); + this.currentLabels.forEach(function(label) { + target.labels.set(label, true); + }); + return this.update({ currentLabels: new Stack(), + labeledTargets: this.labeledTargets.push(target), + defaultLoopTarget: isDefaultLoopTarget + ? target + : this.defaultLoopTarget, + defaultTarget: isDefaultTarget + ? target + : this.defaultTarget }); + }, + nest: function() { + return this.topLevel ? this.update({ topLevel: false }) : this; + }, + allow: function(type) { + switch (type) { + case EXPORT: + if (!this.inModule || this.inFunction || !this.topLevel) + return false; + // FALL THROUGH + + case IMPORT: + return !this.inFunction && this.topLevel; + + case MODULE: + return !this.inFunction && this.topLevel; + + default: + return true; + } + } + }; + + /* + * Script :: (tokenizer, boolean, boolean) -> node + * + * Parses the toplevel and module/function bodies. + */ + function Script(t, inModule, inFunction) { + var n = new Node(t, scriptInit()); + Statements(t, new StaticContext(n, n, inModule, inFunction), n); + return n; + } + + // We extend Array slightly with a top-of-stack method. + definitions.defineProperty(Array.prototype, "top", + function() { + return this.length && this[this.length-1]; + }, false, false, true); + + /* + * Node :: (tokenizer, optional init object) -> node + */ + function Node(t, init) { + var token = t.token; + if (token) { + // If init.type exists it will override token.type. + this.type = token.type; + this.value = token.value; + this.lineno = token.lineno; + if (token.jsdoc) { + this.jsdoc = token.jsdoc; + delete token.jsdoc; + } + + // Start and end are file positions for error handling. + this.start = token.start; + this.end = token.end; + } else { + this.lineno = t.lineno; + } + + // Node uses a tokenizer for debugging (getSource, filename getter). + this.tokenizer = t; + this.children = []; + + for (var prop in init) + this[prop] = init[prop]; + } + + var Np = Node.prototype = {}; + Np.constructor = Node; + Np.toSource = Object.prototype.toSource; + + // Always use push to add operands to an expression, to update start and end. + Np.push = function (kid) { + // kid can be null e.g. [1, , 2]. + if (kid !== null) { + if (kid.start < this.start) + this.start = kid.start; + if (this.end < kid.end) + this.end = kid.end; + } + return this.children.push(kid); + } + + Node.indentLevel = 0; + + function tokenString(tt) { + var t = definitions.tokens[tt]; + return /^\W/.test(t) ? definitions.opTypeNames[t] : t.toUpperCase(); + } + + Np.toString = function () { + var a = []; + for (var i in this) { + if (this.hasOwnProperty(i) && i !== 'type' && i !== 'target') + a.push({id: i, value: this[i]}); + } + a.sort(function (a,b) { return (a.id < b.id) ? -1 : 1; }); + const INDENTATION = " "; + var n = ++Node.indentLevel; + var s = "{\n" + INDENTATION.repeat(n) + "type: " + tokenString(this.type); + for (i = 0; i < a.length; i++) + s += ",\n" + INDENTATION.repeat(n) + a[i].id + ": " + a[i].value; + n = --Node.indentLevel; + s += "\n" + INDENTATION.repeat(n) + "}"; + return s; + } + + Np.getSource = function () { + return this.tokenizer.source.slice(this.start, this.end); + }; + + /* + * Helper init objects for common nodes. + */ + + const LOOP_INIT = { isLoop: true }; + + function blockInit() { + return { type: BLOCK, varDecls: [] }; + } + + function scriptInit() { + return { type: SCRIPT, + funDecls: [], + varDecls: [], + modDefns: new StringMap(), + modAssns: new StringMap(), + modDecls: new StringMap(), + modLoads: new StringMap(), + impDecls: [], + expDecls: [], + exports: new StringMap(), + hasEmptyReturn: false, + hasReturnWithValue: false, + isGenerator: false }; + } + + definitions.defineGetter(Np, "filename", + function() { + return this.tokenizer.filename; + }); + + definitions.defineGetter(Np, "length", + function() { + throw new Error("Node.prototype.length is gone; " + + "use n.children.length instead"); + }); + + definitions.defineProperty(String.prototype, "repeat", + function(n) { + var s = "", t = this + s; + while (--n >= 0) + s += t; + return s; + }, false, false, true); + + function MaybeLeftParen(t, x) { + if (x.parenFreeMode) + return t.match(LEFT_PAREN) ? LEFT_PAREN : END; + return t.mustMatch(LEFT_PAREN).type; + } + + function MaybeRightParen(t, p) { + if (p === LEFT_PAREN) + t.mustMatch(RIGHT_PAREN); + } + + /* + * Statements :: (tokenizer, compiler context, node) -> void + * + * Parses a sequence of Statements. + */ + function Statements(t, x, n) { + try { + while (!t.done && t.peek(true) !== RIGHT_CURLY) + n.push(Statement(t, x)); + } catch (e) { + if (t.done) + t.unexpectedEOF = true; + throw e; + } + } + + function Block(t, x) { + t.mustMatch(LEFT_CURLY); + var n = new Node(t, blockInit()); + Statements(t, x.update({ parentBlock: n }).pushTarget(n), n); + t.mustMatch(RIGHT_CURLY); + return n; + } + + const DECLARED_FORM = 0, EXPRESSED_FORM = 1, STATEMENT_FORM = 2; + + /* + * Export :: (binding node, boolean) -> Export + * + * Static semantic representation of a module export. + */ + function Export(node, isDefinition) { + this.node = node; // the AST node declaring this individual export + this.isDefinition = isDefinition; // is the node an 'export'-annotated definition? + this.resolved = null; // resolved pointer to the target of this export + } + + /* + * registerExport :: (StringMap, EXPORT node) -> void + */ + function registerExport(exports, decl) { + function register(name, exp) { + if (exports.has(name)) + throw new SyntaxError("multiple exports of " + name); + exports.set(name, exp); + } + + switch (decl.type) { + case MODULE: + case FUNCTION: + register(decl.name, new Export(decl, true)); + break; + + case VAR: + for (var i = 0; i < decl.children.length; i++) + register(decl.children[i].name, new Export(decl.children[i], true)); + break; + + case LET: + case CONST: + throw new Error("NYI: " + definitions.tokens[decl.type]); + + case EXPORT: + for (var i = 0; i < decl.pathList.length; i++) { + var path = decl.pathList[i]; + switch (path.type) { + case OBJECT_INIT: + for (var j = 0; j < path.children.length; j++) { + // init :: IDENTIFIER | PROPERTY_INIT + var init = path.children[j]; + if (init.type === IDENTIFIER) + register(init.value, new Export(init, false)); + else + register(init.children[0].value, new Export(init.children[1], false)); + } + break; + + case DOT: + register(path.children[1].value, new Export(path, false)); + break; + + case IDENTIFIER: + register(path.value, new Export(path, false)); + break; + + default: + throw new Error("unexpected export path: " + definitions.tokens[path.type]); + } + } + break; + + default: + throw new Error("unexpected export decl: " + definitions.tokens[exp.type]); + } + } + + /* + * Module :: (node) -> Module + * + * Static semantic representation of a module. + */ + function Module(node) { + var exports = node.body.exports; + var modDefns = node.body.modDefns; + + var exportedModules = new StringMap(); + + exports.forEach(function(name, exp) { + var node = exp.node; + if (node.type === MODULE) { + exportedModules.set(name, node); + } else if (!exp.isDefinition && node.type === IDENTIFIER && modDefns.has(node.value)) { + var mod = modDefns.get(node.value); + exportedModules.set(name, mod); + } + }); + + this.node = node; + this.exports = exports; + this.exportedModules = exportedModules; + } + + /* + * Statement :: (tokenizer, compiler context) -> node + * + * Parses a Statement. + */ + function Statement(t, x) { + var i, label, n, n2, p, c, ss, tt = t.get(true), tt2, x2, x3; + + if (x.blackList[tt]) + throw t.newSyntaxError(definitions.tokens[tt] + " statements only allowed in Harmony"); + if (!x.allow(tt)) + throw t.newSyntaxError(definitions.tokens[tt] + " statement in illegal context"); + + // Cases for statements ending in a right curly return early, avoiding the + // common semicolon insertion magic after this switch. + switch (tt) { + case IMPORT: + n = new Node(t); + n.pathList = ImportPathList(t, x); + x.parentScript.impDecls.push(n); + break; + + case EXPORT: + switch (t.peek()) { + case MODULE: + case FUNCTION: + case LET: + case VAR: + case CONST: + n = Statement(t, x); + n.exported = true; + x.parentScript.expDecls.push(n); + registerExport(x.parentScript.exports, n); + return n; + + default: + n = new Node(t); + n.pathList = ExportPathList(t, x); + break; + } + x.parentScript.expDecls.push(n); + registerExport(x.parentScript.exports, n); + break; + + case MODULE: + n = new Node(t); + t.mustMatch(IDENTIFIER); + label = t.token.value; + + if (t.match(LEFT_CURLY)) { + n.name = label; + n.body = Script(t, true, false); + n.module = new Module(n); + t.mustMatch(RIGHT_CURLY); + x.parentScript.modDefns.set(n.name, n); + return n; + } + + t.unget(); + ModuleVariables(t, x, n); + return n; + + case FUNCTION: + // DECLARED_FORM extends funDecls of x, STATEMENT_FORM doesn't. + return FunctionDefinition(t, x, true, x.topLevel ? DECLARED_FORM : STATEMENT_FORM); + + case LEFT_CURLY: + n = new Node(t, blockInit()); + Statements(t, x.update({ parentBlock: n }).pushTarget(n).nest(), n); + t.mustMatch(RIGHT_CURLY); + return n; + + case IF: + n = new Node(t); + n.condition = HeadExpression(t, x); + x2 = x.pushTarget(n).nest(); + n.thenPart = Statement(t, x2); + n.elsePart = t.match(ELSE, true) ? Statement(t, x2) : null; + return n; + + case SWITCH: + // This allows CASEs after a DEFAULT, which is in the standard. + n = new Node(t, { cases: [], defaultIndex: -1 }); + n.discriminant = HeadExpression(t, x); + x2 = x.pushTarget(n).nest(); + t.mustMatch(LEFT_CURLY); + while ((tt = t.get()) !== RIGHT_CURLY) { + switch (tt) { + case DEFAULT: + if (n.defaultIndex >= 0) + throw t.newSyntaxError("More than one switch default"); + // FALL THROUGH + case CASE: + n2 = new Node(t); + if (tt === DEFAULT) + n.defaultIndex = n.cases.length; + else + n2.caseLabel = Expression(t, x2, COLON); + break; + + default: + throw t.newSyntaxError("Invalid switch case"); + } + t.mustMatch(COLON); + n2.statements = new Node(t, blockInit()); + while ((tt=t.peek(true)) !== CASE && tt !== DEFAULT && + tt !== RIGHT_CURLY) + n2.statements.push(Statement(t, x2)); + n.cases.push(n2); + } + return n; + + case FOR: + n = new Node(t, LOOP_INIT); + if (t.match(IDENTIFIER)) { + if (t.token.value === "each") + n.isEach = true; + else + t.unget(); + } + if (!x.parenFreeMode) + t.mustMatch(LEFT_PAREN); + x2 = x.pushTarget(n).nest(); + x3 = x.update({ inForLoopInit: true }); + n2 = null; + if ((tt = t.peek(true)) !== SEMICOLON) { + if (tt === VAR || tt === CONST) { + t.get(); + n2 = Variables(t, x3); + } else if (tt === LET) { + t.get(); + if (t.peek() === LEFT_PAREN) { + n2 = LetBlock(t, x3, false); + } else { + // Let in for head, we need to add an implicit block + // around the rest of the for. + x3.parentBlock = n; + n.varDecls = []; + n2 = Variables(t, x3); + } + } else { + n2 = Expression(t, x3); + } + } + if (n2 && t.match(IN)) { + n.type = FOR_IN; + n.object = Expression(t, x3); + if (n2.type === VAR || n2.type === LET) { + c = n2.children; + + // Destructuring turns one decl into multiples, so either + // there must be only one destructuring or only one + // decl. + if (c.length !== 1 && n2.destructurings.length !== 1) { + throw new SyntaxError("Invalid for..in left-hand side", + t.filename, n2.lineno); + } + if (n2.destructurings.length > 0) { + n.iterator = n2.destructurings[0]; + } else { + n.iterator = c[0]; + } + n.varDecl = n2; + } else { + if (n2.type === ARRAY_INIT || n2.type === OBJECT_INIT) { + n2.destructuredNames = checkDestructuring(t, x3, n2); + } + n.iterator = n2; + } + } else { + x3.inForLoopInit = false; + n.setup = n2; + t.mustMatch(SEMICOLON); + if (n.isEach) + throw t.newSyntaxError("Invalid for each..in loop"); + n.condition = (t.peek(true) === SEMICOLON) + ? null + : Expression(t, x3); + t.mustMatch(SEMICOLON); + tt2 = t.peek(true); + n.update = (x.parenFreeMode + ? tt2 === LEFT_CURLY || definitions.isStatementStartCode[tt2] + : tt2 === RIGHT_PAREN) + ? null + : Expression(t, x3); + } + if (!x.parenFreeMode) + t.mustMatch(RIGHT_PAREN); + n.body = Statement(t, x2); + return n; + + case WHILE: + n = new Node(t, { isLoop: true }); + n.condition = HeadExpression(t, x); + n.body = Statement(t, x.pushTarget(n).nest()); + return n; + + case DO: + n = new Node(t, { isLoop: true }); + n.body = Statement(t, x.pushTarget(n).nest()); + t.mustMatch(WHILE); + n.condition = HeadExpression(t, x); + if (!x.ecmaStrictMode) { + // + + + + +

    b ? 1 : 0; + }; + callback(null, _map(results.sort(fn), function (x) { + return x.value; + })); + } + }); + }; + + async.auto = function (tasks, callback) { + callback = callback || function () {}; + var keys = _keys(tasks); + if (!keys.length) { + return callback(null); + } + + var completed = []; + + var listeners = []; + var addListener = function (fn) { + listeners.unshift(fn); + }; + var removeListener = function (fn) { + for (var i = 0; i < listeners.length; i += 1) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + return; + } + } + }; + var taskComplete = function () { + _forEach(listeners, function (fn) { + fn(); + }); + }; + + addListener(function () { + if (completed.length === keys.length) { + callback(null); + } + }); + + _forEach(keys, function (k) { + var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; + var taskCallback = function (err) { + if (err) { + callback(err); + // stop subsequent errors hitting callback multiple times + callback = function () {}; + } + else { + completed.push(k); + taskComplete(); + } + }; + var requires = task.slice(0, Math.abs(task.length - 1)) || []; + var ready = function () { + return _reduce(requires, function (a, x) { + return (a && _indexOf(completed, x) !== -1); + }, true); + }; + if (ready()) { + task[task.length - 1](taskCallback); + } + else { + var listener = function () { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback); + } + }; + addListener(listener); + } + }); + }; + + async.waterfall = function (tasks, callback) { + if (!tasks.length) { + return callback(); + } + callback = callback || function () {}; + var wrapIterator = function (iterator) { + return function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + async.nextTick(function () { + iterator.apply(null, args); + }); + } + }; + }; + wrapIterator(async.iterator(tasks))(); + }; + + async.parallel = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.map(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args || null); + }); + } + }, callback); + } + else { + var results = {}; + async.forEach(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.series = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.mapSeries(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args || null); + }); + } + }, callback); + } + else { + var results = {}; + async.forEachSeries(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.iterator = function (tasks) { + var makeCallback = function (index) { + var fn = function () { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + }; + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + }; + return makeCallback(0); + }; + + async.apply = function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ); + }; + }; + + var _concat = function (eachfn, arr, fn, callback) { + var r = []; + eachfn(arr, function (x, cb) { + fn(x, function (err, y) { + r = r.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, r); + }); + }; + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + if (test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.whilst(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.until = function (test, iterator, callback) { + if (!test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.until(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.queue = function (worker, concurrency) { + var workers = 0; + var tasks = []; + var q = { + concurrency: concurrency, + push: function (data, callback) { + tasks.push({data: data, callback: callback}); + async.nextTick(q.process); + }, + process: function () { + if (workers < q.concurrency && tasks.length) { + var task = tasks.splice(0, 1)[0]; + workers += 1; + worker(task.data, function () { + workers -= 1; + if (task.callback) { + task.callback.apply(task, arguments); + } + q.process(); + }); + } + }, + length: function () { + return tasks.length; + } + }; + return q; + }; + + var _console_fn = function (name) { + return function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + fn.apply(null, args.concat([function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (typeof console !== 'undefined') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _forEach(args, function (x) { + console[name](x); + }); + } + } + }])); + }; + }; + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + hasher = hasher || function (x) { + return x; + }; + return function () { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (key in memo) { + callback.apply(null, memo[key]); + } + else { + fn.apply(null, args.concat([function () { + memo[key] = arguments; + callback.apply(null, arguments); + }])); + } + }; + }; + +}()); diff --git a/node_modules/nodeunit/deps/ejs.js b/node_modules/nodeunit/deps/ejs.js new file mode 100644 index 00000000..f6abf29f --- /dev/null +++ b/node_modules/nodeunit/deps/ejs.js @@ -0,0 +1,125 @@ + +/*! + * EJS + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var sys = require('sys'); + +/** + * Library version. + */ + +exports.version = '0.0.3'; + +/** + * Intermediate js cache. + * + * @type Object + */ + +var cache = {}; + +/** + * Clear intermediate js cache. + * + * @api public + */ + +exports.clearCache = function(){ + cache = {}; +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +function escape(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +} + +/** + * Parse the given `str` of ejs, returning the function body. + * + * @param {String} str + * @return {String} + * @api public + */ + +var parse = exports.parse = function(str){ + return 'var buf = [];\n' + + "with (locals) {\nbuf.push('" + + String(str) + .replace(/[\r\t]/g, " ") + .replace(/\n/g, "\\n") + .split("<%").join("\t") + .replace(/((^|%>)[^\t]*)'/g, "$1\r") + .replace(/\t=(.*?)%>/g, "', escape($1) ,'") + .replace(/\t-(.*?)%>/g, "', $1 ,'") + .split("\t").join("');") + .split("%>").join("buf.push('") + .split("\r").join("\\'") + + "');\n}\nreturn buf.join('');"; +}; + +/** + * Compile the given `str` of ejs into a `Function`. + * + * @param {String} str + * @param {Object} options + * @return {Function} + * @api public + */ + +var compile = exports.compile = function(str, options){ + if (options.debug) sys.puts(parse(str)); + return new Function('locals, escape', parse(str)); +}; + +/** + * Render the given `str` of ejs. + * + * Options: + * + * - `locals` Local variables object + * - `cache` Compiled functions are cached, requires `filename` + * - `filename` Used by `cache` to key caches + * - `context|scope` Function execution context + * - `debug` Output generated function body + * + * @param {String} str + * @param {Object} options + * @return {String} + * @api public + */ + +exports.render = function(str, options){ + var fn, + options = options || {}; + if (options.cache) { + if (options.filename) { + fn = cache[options.filename] = compile(str, options); + } else { + throw new Error('"cache" option requires "filename".'); + } + } else { + fn = compile(str, options); + } + return fn.call( + options.context || options.scope, + options.locals || {}, + escape); +}; \ No newline at end of file diff --git a/node_modules/nodeunit/deps/json2.js b/node_modules/nodeunit/deps/json2.js new file mode 100644 index 00000000..22b44d96 --- /dev/null +++ b/node_modules/nodeunit/deps/json2.js @@ -0,0 +1,483 @@ +/* + http://www.JSON.org/json2.js + 2010-11-17 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, strict: false, regexp: false */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (!this.JSON) { + this.JSON = {}; +} + +(function () { + "use strict"; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? + '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ +.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') +.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') +.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); diff --git a/node_modules/nodeunit/doc/nodeunit.md b/node_modules/nodeunit/doc/nodeunit.md new file mode 100644 index 00000000..efde75cd --- /dev/null +++ b/node_modules/nodeunit/doc/nodeunit.md @@ -0,0 +1,60 @@ +nodeunit(1) -- simple node.js unit testing tool +=============================================== + +## SYNOPSIS + + nodeunit [options] [ ...] + +## DESCRIPTION + +Nodeunit is a simple unit testing tool based on the node.js assert module. + +* Simple to use +* Just export the tests from a module +* Helps you avoid common pitfalls when testing asynchronous code +* Easy to add test cases with setUp and tearDown functions if you wish +* Allows the use of mocks and stubs + +## OPTIONS + + __--config FILE__: + Load config options from a JSON file, allows the customisation + of color schemes for the default test reporter etc. + See bin/nodeunit.json for current available options. + + __--reporter FILE__: + You can set the test reporter to a custom module or on of the modules + in nodeunit/lib/reporters, when omitted, the default test runner is used. + + __--list-reporters__: + List available build-in reporters. + + __-h__, __--help__: + Display the help and exit. + + __-v__, __--version__: + Output version information and exit. + + ____: + You can run nodeunit on specific files or on all *\*.js* files inside + a directory. + +## AUTHORS + +Written by Caolan McMahon and other nodeunit contributors. +Contributors list: . + +## REPORTING BUGS + +Report nodeunit bugs to . + +## COPYRIGHT + +Copyright © 2010 Caolan McMahon. +Nodeunit has been released under the MIT license: +. + +## SEE ALSO + +node(1) + diff --git a/node_modules/nodeunit/examples/browser/nodeunit.js b/node_modules/nodeunit/examples/browser/nodeunit.js new file mode 100644 index 00000000..8c12b0f8 --- /dev/null +++ b/node_modules/nodeunit/examples/browser/nodeunit.js @@ -0,0 +1,1757 @@ +/*! + * Nodeunit + * https://github.com/caolan/nodeunit + * Copyright (c) 2010 Caolan McMahon + * MIT Licensed + * + * json2.js + * http://www.JSON.org/json2.js + * Public Domain. + * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + */ +nodeunit = (function(){ +/* + http://www.JSON.org/json2.js + 2010-11-17 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, strict: false, regexp: false */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (!this.JSON) { + this.JSON = {}; +} + +(function () { + "use strict"; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? + '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ +.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') +.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') +.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); +var assert = {}; +var types = {}; +var core = {}; +var nodeunit = {}; +var reporter = {}; +(function(){ + + var async = {}; + + // global on the server, window in the browser + var root = this; + var previous_async = root.async; + + if(typeof module !== 'undefined' && module.exports) module.exports = async; + else root.async = async; + + async.noConflict = function(){ + root.async = previous_async; + return async; + }; + + //// cross-browser compatiblity functions //// + + var _forEach = function(arr, iterator){ + if(arr.forEach) return arr.forEach(iterator); + for(var i=0; i b ? 1 : 0; + }), function(x){return x.value;})); + }) + }; + + async.auto = function(tasks, callback){ + callback = callback || function(){}; + var keys = _keys(tasks); + if(!keys.length) return callback(null); + + var completed = []; + + var listeners = []; + var addListener = function(fn){ + listeners.unshift(fn); + }; + var removeListener = function(fn){ + for(var i=0; i +// +// 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 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. + + +var pSlice = Array.prototype.slice; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = exports; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({message: message, actual: actual, expected: expected}) + +assert.AssertionError = function AssertionError (options) { + this.name = "AssertionError"; + this.message = options.message; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } +}; +// code from util.inherits in node +assert.AssertionError.super_ = Error; + + +// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call +// TODO: test what effect this may have +var ctor = function () { this.constructor = assert.AssertionError; }; +ctor.prototype = Error.prototype; +assert.AssertionError.prototype = new ctor(); + + +assert.AssertionError.prototype.toString = function() { + if (this.message) { + return [this.name+":", this.message].join(' '); + } else { + return [ this.name+":" + , JSON.stringify(this.expected ) + , this.operator + , JSON.stringify(this.actual) + ].join(" "); + } +}; + +// assert.AssertionError instanceof Error + +assert.AssertionError.__proto__ = Error.prototype; + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +assert.ok = function ok(value, message) { + if (!!!value) fail(value, true, message, "==", assert.ok); +}; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, "==", assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, "!=", assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, "deepEqual", assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3. Other pairs that do not both pass typeof value == "object", + // equivalence is determined by ==. + } else if (typeof actual != 'object' && typeof expected != 'object') { + return actual == expected; + + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical "prototype" property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isUndefinedOrNull (value) { + return value === null || value === undefined; +} + +function isArguments (object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv (a, b) { + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical "prototype" property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try{ + var ka = _keys(a), + kb = _keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key] )) + return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, "===", assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as determined by !==. +// assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, "!==", assert.notStrictEqual); + } +}; + +function _throws (shouldThrow, block, err, message) { + var exception = null, + threw = false, + typematters = true; + + message = message || ""; + + //handle optional arguments + if (arguments.length == 3) { + if (typeof(err) == "string") { + message = err; + typematters = false; + } + } else if (arguments.length == 2) { + typematters = false; + } + + try { + block(); + } catch (e) { + threw = true; + exception = e; + } + + if (shouldThrow && !threw) { + fail( "Missing expected exception" + + (err && err.name ? " ("+err.name+")." : '.') + + (message ? " " + message : "") + ); + } + if (!shouldThrow && threw && typematters && exception instanceof err) { + fail( "Got unwanted exception" + + (err && err.name ? " ("+err.name+")." : '.') + + (message ? " " + message : "") + ); + } + if ((shouldThrow && threw && typematters && !(exception instanceof err)) || + (!shouldThrow && threw)) { + throw exception; + } +}; + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function (err) { if (err) {throw err;}}; +})(assert); +(function(exports){ +/*! + * Nodeunit + * Copyright (c) 2010 Caolan McMahon + * MIT Licensed + * + * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! + * Only code on that line will be removed, its mostly to avoid requiring code + * that is node specific + */ + +/** + * Module dependencies + */ + + + +/** + * Creates assertion objects representing the result of an assert call. + * Accepts an object or AssertionError as its argument. + * + * @param {object} obj + * @api public + */ + +exports.assertion = function (obj) { + return { + method: obj.method || '', + message: obj.message || (obj.error && obj.error.message) || '', + error: obj.error, + passed: function () { + return !this.error; + }, + failed: function () { + return Boolean(this.error); + } + }; +}; + +/** + * Creates an assertion list object representing a group of assertions. + * Accepts an array of assertion objects. + * + * @param {Array} arr + * @param {Number} duration + * @api public + */ + +exports.assertionList = function (arr, duration) { + var that = arr || []; + that.failures = function () { + var failures = 0; + for (var i=0; i'; +}; + + +/** + * Run all tests within each module, reporting the results + * + * @param {Array} files + * @api public + */ + +exports.run = function (modules, options) { + var start = new Date().getTime(); + exports.addStyles(); + + var html = ''; + nodeunit.runModules(modules, { + moduleStart: function (name) { + html += '

    ' + name + '

    '; + html += '
      '; + }, + testDone: function (name, assertions) { + if (!assertions.failures()) { + html += '
    1. ' + name + '
    2. '; + } + else { + html += '
    3. ' + name; + for (var i=0; i'; + } + html += '
      ';
      +                        html += a.error.stack || a.error;
      +                        html += '
      '; + } + }; + html += '
    4. '; + } + }, + moduleDone: function () { + html += '
    '; + }, + done: function (assertions) { + var end = new Date().getTime(); + var duration = end - start; + if (assertions.failures()) { + html += '

    FAILURES: ' + assertions.failures() + + '/' + assertions.length + ' assertions failed (' + + assertions.duration + 'ms)

    '; + } + else { + html += '

    OK: ' + assertions.length + + ' assertions (' + assertions.duration + 'ms)

    '; + } + document.body.innerHTML += html; + } + }); +}; +})(reporter); +nodeunit = core; +nodeunit.assert = assert; +nodeunit.reporter = reporter; +nodeunit.run = reporter.run; +return nodeunit; })(); diff --git a/node_modules/nodeunit/examples/browser/suite1.js b/node_modules/nodeunit/examples/browser/suite1.js new file mode 100644 index 00000000..0d5fc90e --- /dev/null +++ b/node_modules/nodeunit/examples/browser/suite1.js @@ -0,0 +1,12 @@ +this.suite1 = { + 'test one': function (test) { + test.ok(true, 'everythings ok'); + setTimeout(function () { + test.done(); + }, 10); + }, + 'apples and oranges': function (test) { + test.equal('apples', 'oranges', 'comparing apples and oranges'); + test.done(); + } +}; diff --git a/node_modules/nodeunit/examples/browser/suite2.js b/node_modules/nodeunit/examples/browser/suite2.js new file mode 100644 index 00000000..c7288e8d --- /dev/null +++ b/node_modules/nodeunit/examples/browser/suite2.js @@ -0,0 +1,13 @@ +this.suite2 = { + 'another test': function (test) { + setTimeout(function () { + // lots of assertions + test.ok(true, 'everythings ok'); + test.ok(true, 'everythings ok'); + test.ok(true, 'everythings ok'); + test.ok(true, 'everythings ok'); + test.ok(true, 'everythings ok'); + test.done(); + }, 10); + } +}; diff --git a/node_modules/nodeunit/examples/browser/test.html b/node_modules/nodeunit/examples/browser/test.html new file mode 100644 index 00000000..e9f8180f --- /dev/null +++ b/node_modules/nodeunit/examples/browser/test.html @@ -0,0 +1,16 @@ + + + Example tests + + + + + + + + diff --git a/node_modules/nodeunit/img/example_fail.png b/node_modules/nodeunit/img/example_fail.png new file mode 100644 index 00000000..78ff4258 Binary files /dev/null and b/node_modules/nodeunit/img/example_fail.png differ diff --git a/node_modules/nodeunit/img/example_pass.png b/node_modules/nodeunit/img/example_pass.png new file mode 100644 index 00000000..069d7169 Binary files /dev/null and b/node_modules/nodeunit/img/example_pass.png differ diff --git a/node_modules/nodeunit/index.js b/node_modules/nodeunit/index.js new file mode 100644 index 00000000..07867d01 --- /dev/null +++ b/node_modules/nodeunit/index.js @@ -0,0 +1,3 @@ +// This file is just added for convenience so this repository can be +// directly checked out into a project's deps folder +module.exports = require('./lib/nodeunit'); diff --git a/node_modules/nodeunit/lib/assert.js b/node_modules/nodeunit/lib/assert.js new file mode 100644 index 00000000..7f7bbdf4 --- /dev/null +++ b/node_modules/nodeunit/lib/assert.js @@ -0,0 +1,316 @@ +/** + * This file is based on the node.js assert module, but with some small + * changes for browser-compatibility + * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! + */ + + +/** + * Added for browser compatibility + */ + +var _keys = function(obj){ + if(Object.keys) return Object.keys(obj); + var keys = []; + for(var k in obj){ + if(obj.hasOwnProperty(k)) keys.push(k); + } + return keys; +}; + + + +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.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 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. + + +var pSlice = Array.prototype.slice; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = exports; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({message: message, actual: actual, expected: expected}) + +assert.AssertionError = function AssertionError (options) { + this.name = "AssertionError"; + this.message = options.message; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } +}; +// code from util.inherits in node +assert.AssertionError.super_ = Error; + + +// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call +// TODO: test what effect this may have +var ctor = function () { this.constructor = assert.AssertionError; }; +ctor.prototype = Error.prototype; +assert.AssertionError.prototype = new ctor(); + + +assert.AssertionError.prototype.toString = function() { + if (this.message) { + return [this.name+":", this.message].join(' '); + } else { + return [ this.name+":" + , JSON.stringify(this.expected ) + , this.operator + , JSON.stringify(this.actual) + ].join(" "); + } +}; + +// assert.AssertionError instanceof Error + +assert.AssertionError.__proto__ = Error.prototype; + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +assert.ok = function ok(value, message) { + if (!!!value) fail(value, true, message, "==", assert.ok); +}; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, "==", assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, "!=", assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, "deepEqual", assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3. Other pairs that do not both pass typeof value == "object", + // equivalence is determined by ==. + } else if (typeof actual != 'object' && typeof expected != 'object') { + return actual == expected; + + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical "prototype" property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isUndefinedOrNull (value) { + return value === null || value === undefined; +} + +function isArguments (object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv (a, b) { + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical "prototype" property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try{ + var ka = _keys(a), + kb = _keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key] )) + return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, "===", assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as determined by !==. +// assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, "!==", assert.notStrictEqual); + } +}; + +function _throws (shouldThrow, block, err, message) { + var exception = null, + threw = false, + typematters = true; + + message = message || ""; + + //handle optional arguments + if (arguments.length == 3) { + if (typeof(err) == "string") { + message = err; + typematters = false; + } + } else if (arguments.length == 2) { + typematters = false; + } + + try { + block(); + } catch (e) { + threw = true; + exception = e; + } + + if (shouldThrow && !threw) { + fail( "Missing expected exception" + + (err && err.name ? " ("+err.name+")." : '.') + + (message ? " " + message : "") + ); + } + if (!shouldThrow && threw && typematters && exception instanceof err) { + fail( "Got unwanted exception" + + (err && err.name ? " ("+err.name+")." : '.') + + (message ? " " + message : "") + ); + } + if ((shouldThrow && threw && typematters && !(exception instanceof err)) || + (!shouldThrow && threw)) { + throw exception; + } +}; + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert['throws'] = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function (err) { if (err) {throw err;}}; diff --git a/node_modules/nodeunit/lib/core.js b/node_modules/nodeunit/lib/core.js new file mode 100644 index 00000000..981d7c63 --- /dev/null +++ b/node_modules/nodeunit/lib/core.js @@ -0,0 +1,236 @@ +/*! + * Nodeunit + * Copyright (c) 2010 Caolan McMahon + * MIT Licensed + * + * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! + * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. + * Only code on that line will be removed, its mostly to avoid requiring code + * that is node specific + */ + +/** + * Module dependencies + */ + +var async = require('../deps/async'), //@REMOVE_LINE_FOR_BROWSER + types = require('./types'); //@REMOVE_LINE_FOR_BROWSER + + +/** + * Added for browser compatibility + */ + +var _keys = function(obj){ + if(Object.keys) return Object.keys(obj); + var keys = []; + for(var k in obj){ + if(obj.hasOwnProperty(k)) keys.push(k); + } + return keys; +}; + + +/** + * Runs a test function (fn) from a loaded module. After the test function + * calls test.done(), the callback is executed with an assertionList as its + * second argument. + * + * @param {String} name + * @param {Function} fn + * @param {Object} opt + * @param {Function} callback + * @api public + */ + +exports.runTest = function (name, fn, opt, callback) { + var options = types.options(opt); + + options.testStart(name); + var start = new Date().getTime(); + var test = types.test(name, start, options, callback); + + try { + fn(test); + } + catch (e) { + test.done(e); + } +}; + +/** + * Takes an object containing test functions or other test suites as properties + * and runs each in series. After all tests have completed, the callback is + * called with a list of all assertions as the second argument. + * + * If a name is passed to this function it is prepended to all test and suite + * names that run within it. + * + * @param {String} name + * @param {Object} suite + * @param {Object} opt + * @param {Function} callback + * @api public + */ + +exports.runSuite = function (name, suite, opt, callback) { + var keys = _keys(suite); + + async.concatSeries(keys, function (k, cb) { + var prop = suite[k], _name; + + _name = name ? [].concat(name, k) : [k]; + + _name.toString = function () { + // fallback for old one + return this.join(' - '); + }; + + if (typeof prop === 'function') { + exports.runTest(_name, suite[k], opt, cb); + } + else { + exports.runSuite(_name, suite[k], opt, cb); + } + }, callback); +}; + +/** + * Run each exported test function or test suite from a loaded module. + * + * @param {String} name + * @param {Object} mod + * @param {Object} opt + * @param {Function} callback + * @api public + */ + +exports.runModule = function (name, mod, opt, callback) { + var options = types.options(opt); + + options.moduleStart(name); + var start = new Date().getTime(); + + exports.runSuite(null, mod, opt, function (err, a_list) { + var end = new Date().getTime(); + var assertion_list = types.assertionList(a_list, end - start); + options.moduleDone(name, assertion_list); + callback(null, a_list); + }); +}; + +/** + * Treats an object literal as a list of modules keyed by name. Runs each + * module and finished with calling 'done'. You can think of this as a browser + * safe alternative to runFiles in the nodeunit module. + * + * @param {Object} modules + * @param {Object} opt + * @api public + */ + +// TODO: add proper unit tests for this function +exports.runModules = function (modules, opt) { + var all_assertions = []; + var options = types.options(opt); + var start = new Date().getTime(); + + async.concatSeries(_keys(modules), function (k, cb) { + exports.runModule(k, modules[k], options, cb); + }, + function (err, all_assertions) { + var end = new Date().getTime(); + options.done(types.assertionList(all_assertions, end - start)); + }); +}; + + +/** + * Wraps a test function with setUp and tearDown functions. + * Used by testCase. + * + * @param {Function} setUp + * @param {Function} tearDown + * @param {Function} fn + * @api private + */ + +var wrapTest = function (setUp, tearDown, fn) { + return function (test) { + var context = {}; + if (tearDown) { + var done = test.done; + test.done = function (err) { + try { + tearDown.call(context, function (err2) { + if (err && err2) { + test._assertion_list.push( + types.assertion({error: err}) + ); + return done(err2); + } + done(err || err2); + }); + } + catch (e) { + done(e); + } + }; + } + if (setUp) { + setUp.call(context, function (err) { + if (err) { + return test.done(err); + } + fn.call(context, test); + }); + } + else { + fn.call(context, test); + } + } +}; + + +/** + * Wraps a group of tests with setUp and tearDown functions. + * Used by testCase. + * + * @param {Function} setUp + * @param {Function} tearDown + * @param {Object} group + * @api private + */ + +var wrapGroup = function (setUp, tearDown, group) { + var tests = {}; + var keys = _keys(group); + for (var i=0; i(' + + '' + assertions.failures() + ', ' + + '' + assertions.passes() + ', ' + + assertions.length + + ')'; + test.className = assertions.failures() ? 'fail': 'pass'; + test.appendChild(strong); + + var aList = document.createElement('ol'); + aList.style.display = 'none'; + test.onclick = function () { + var d = aList.style.display; + aList.style.display = (d == 'none') ? 'block': 'none'; + }; + for (var i=0; i' + (a.error.stack || a.error) + '

    '; + li.className = 'fail'; + } + else { + li.innerHTML = a.message || a.method || 'no message'; + li.className = 'pass'; + } + aList.appendChild(li); + } + test.appendChild(aList); + tests.appendChild(test); + }, + done: function (assertions) { + var end = new Date().getTime(); + var duration = end - start; + + var failures = assertions.failures(); + banner.className = failures ? 'fail': 'pass'; + + result.innerHTML = 'Tests completed in ' + duration + + ' milliseconds.
    ' + + assertions.passes() + ' assertions of ' + + '' + assertions.length + ' passed, ' + + assertions.failures() + ' failed.'; + } + }); +}; diff --git a/node_modules/nodeunit/lib/reporters/default.js b/node_modules/nodeunit/lib/reporters/default.js new file mode 100644 index 00000000..683b66de --- /dev/null +++ b/node_modules/nodeunit/lib/reporters/default.js @@ -0,0 +1,131 @@ +/*! + * Nodeunit + * Copyright (c) 2010 Caolan McMahon + * MIT Licensed + */ + +/** + * Module dependencies + */ + +var nodeunit = require('../nodeunit'), + utils = require('../utils'), + fs = require('fs'), + sys = require('sys'), + track = require('../track'), + path = require('path'); + AssertionError = require('../assert').AssertionError; + +/** + * Reporter info string + */ + +exports.info = "Default tests reporter"; + + +/** + * Run all tests within each module, reporting the results to the command-line. + * + * @param {Array} files + * @api public + */ + +exports.run = function (files, options) { + + if (!options) { + // load default options + var content = fs.readFileSync( + __dirname + '/../../bin/nodeunit.json', 'utf8' + ); + options = JSON.parse(content); + } + + var error = function (str) { + return options.error_prefix + str + options.error_suffix; + }; + var ok = function (str) { + return options.ok_prefix + str + options.ok_suffix; + }; + var bold = function (str) { + return options.bold_prefix + str + options.bold_suffix; + }; + var assertion_message = function (str) { + return options.assertion_prefix + str + options.assertion_suffix; + }; + + var start = new Date().getTime(); + var paths = files.map(function (p) { + return path.join(process.cwd(), p); + }); + var tracker = track.createTracker(function (tracker) { + if (tracker.unfinished()) { + sys.puts(''); + sys.puts(error(bold( + 'FAILURES: Undone tests (or their setups/teardowns): ' + ))); + var names = tracker.names(); + for (var i = 0; i < names.length; i += 1) { + sys.puts('- ' + names[i]); + } + sys.puts(''); + sys.puts('To fix this, make sure all tests call test.done()'); + process.reallyExit(tracker.unfinished()); + } + }); + + nodeunit.runFiles(paths, { + moduleStart: function (name) { + sys.puts('\n' + bold(name)); + }, + testDone: function (name, assertions) { + tracker.remove(name); + + if (!assertions.failures()) { + sys.puts('✔ ' + name); + } + else { + sys.puts(error('✖ ' + name) + '\n'); + assertions.forEach(function (a) { + if (a.failed()) { + a = utils.betterErrors(a); + if (a.error instanceof AssertionError && a.message) { + sys.puts( + 'Assertion Message: ' + + assertion_message(a.message) + ); + } + sys.puts(a.error.stack + '\n'); + } + }); + } + }, + done: function (assertions) { + var end = new Date().getTime(); + var duration = end - start; + if (assertions.failures()) { + sys.puts( + '\n' + bold(error('FAILURES: ')) + assertions.failures() + + '/' + assertions.length + ' assertions failed (' + + assertions.duration + 'ms)' + ); + } + else { + sys.puts( + '\n' + bold(ok('OK: ')) + assertions.length + + ' assertions (' + assertions.duration + 'ms)' + ); + } + // alexgorbatchev 2010-11-10 :: should be able to flush stdout + // here, but doesn't seem to work, instead delay the exit to give + // enough to time flush. + // process.stdout.flush() + // process.stdout.end() + setTimeout(function () { + process.reallyExit(assertions.failures()); + }, 10); + }, + testStart: function(name) { + tracker.put(name); + } + }); +}; diff --git a/node_modules/nodeunit/lib/reporters/html.js b/node_modules/nodeunit/lib/reporters/html.js new file mode 100644 index 00000000..a693c2d1 --- /dev/null +++ b/node_modules/nodeunit/lib/reporters/html.js @@ -0,0 +1,112 @@ +/*! + * Nodeunit + * Copyright (c) 2010 Caolan McMahon + * MIT Licensed + */ + +/** + * Module dependencies + */ + +var nodeunit = require('../nodeunit'), + utils = require('../utils'), + fs = require('fs'), + sys = require('sys'), + path = require('path'), + AssertionError = require('assert').AssertionError; + +/** + * Reporter info string + */ + +exports.info = "Report tests result as HTML"; + +/** + * Run all tests within each module, reporting the results to the command-line. + * + * @param {Array} files + * @api public + */ + +exports.run = function (files, options) { + + var start = new Date().getTime(); + var paths = files.map(function (p) { + return path.join(process.cwd(), p); + }); + + sys.puts(''); + sys.puts(''); + sys.puts(''); + sys.puts(''); + sys.puts(''); + sys.puts(''); + nodeunit.runFiles(paths, { + moduleStart: function (name) { + sys.puts('

    ' + name + '

    '); + sys.puts('
      '); + }, + testDone: function (name, assertions) { + if (!assertions.failures()) { + sys.puts('
    1. ' + name + '
    2. '); + } + else { + sys.puts('
    3. ' + name); + assertions.forEach(function (a) { + if (a.failed()) { + a = utils.betterErrors(a); + if (a.error instanceof AssertionError && a.message) { + sys.puts('
      ' + + 'Assertion Message: ' + a.message + + '
      '); + } + sys.puts('
      ');
      +                        sys.puts(a.error.stack);
      +                        sys.puts('
      '); + } + }); + sys.puts('
    4. '); + } + }, + moduleDone: function () { + sys.puts('
    '); + }, + done: function (assertions) { + var end = new Date().getTime(); + var duration = end - start; + if (assertions.failures()) { + sys.puts( + '

    FAILURES: ' + assertions.failures() + + '/' + assertions.length + ' assertions failed (' + + assertions.duration + 'ms)

    ' + ); + } + else { + sys.puts( + '

    OK: ' + assertions.length + + ' assertions (' + assertions.duration + 'ms)

    ' + ); + } + sys.puts(''); + // should be able to flush stdout here, but doesn't seem to work, + // instead delay the exit to give enough to time flush. + setTimeout(function () { + process.reallyExit(assertions.failures()); + }, 10); + } + }); + +}; diff --git a/node_modules/nodeunit/lib/reporters/index.js b/node_modules/nodeunit/lib/reporters/index.js new file mode 100644 index 00000000..bbaf800d --- /dev/null +++ b/node_modules/nodeunit/lib/reporters/index.js @@ -0,0 +1,9 @@ +module.exports = { + 'junit': require('./junit'), + 'default': require('./default'), + 'skip_passed': require('./skip_passed'), + 'minimal': require('./minimal'), + 'html': require('./html') + // browser test reporter is not listed because it cannot be used + // with the command line tool, only inside a browser. +}; diff --git a/node_modules/nodeunit/lib/reporters/junit.js b/node_modules/nodeunit/lib/reporters/junit.js new file mode 100644 index 00000000..7ff8a7d5 --- /dev/null +++ b/node_modules/nodeunit/lib/reporters/junit.js @@ -0,0 +1,186 @@ +/*! + * Nodeunit + * Copyright (c) 2010 Caolan McMahon + * MIT Licensed + */ + +/** + * Module dependencies + */ + +var nodeunit = require('../nodeunit'), + utils = require('../utils'), + fs = require('fs'), + sys = require('sys'), + path = require('path'), + async = require('../../deps/async'), + AssertionError = require('assert').AssertionError, + child_process = require('child_process'), + ejs = require('../../deps/ejs'); + + +/** + * Reporter info string + */ + +exports.info = "jUnit XML test reports"; + + +/** + * Ensures a directory exists using mkdir -p. + * + * @param {String} path + * @param {Function} callback + * @api private + */ + +var ensureDir = function (path, callback) { + var mkdir = child_process.spawn('mkdir', ['-p', path]); + mkdir.on('error', function (err) { + callback(err); + callback = function(){}; + }); + mkdir.on('exit', function (code) { + if (code === 0) callback(); + else callback(new Error('mkdir exited with code: ' + code)); + }); +}; + + +/** + * Returns absolute version of a path. Relative paths are interpreted + * relative to process.cwd() or the cwd parameter. Paths that are already + * absolute are returned unaltered. + * + * @param {String} p + * @param {String} cwd + * @return {String} + * @api public + */ + +var abspath = function (p, /*optional*/cwd) { + if (p[0] === '/') return p; + cwd = cwd || process.cwd(); + return path.normalize(path.join(cwd, p)); +}; + + +/** + * Run all tests within each module, reporting the results to the command-line, + * then writes out junit-compatible xml documents. + * + * @param {Array} files + * @api public + */ + +exports.run = function (files, opts, callback) { + if (!opts.output) { + console.error( + 'Error: No output directory defined.\n' + + '\tEither add an "output" property to your nodeunit.json config ' + + 'file, or\n\tuse the --output command line option.' + ); + return; + } + opts.output = abspath(opts.output); + var error = function (str) { + return opts.error_prefix + str + opts.error_suffix; + }; + var ok = function (str) { + return opts.ok_prefix + str + opts.ok_suffix; + }; + var bold = function (str) { + return opts.bold_prefix + str + opts.bold_suffix; + }; + + var start = new Date().getTime(); + var paths = files.map(function (p) { + return path.join(process.cwd(), p); + }); + + var modules = {} + var curModule; + + nodeunit.runFiles(paths, { + moduleStart: function (name) { + curModule = { + errorCount: 0, + failureCount: 0, + tests: 0, + testcases: [], + name: name + }; + modules[name] = curModule; + }, + testDone: function (name, assertions) { + var testcase = {name: name}; + for (var i=0; i [ \.\.\.] +. +.fi +. +.SH "DESCRIPTION" +Nodeunit is a simple unit testing tool based on the node\.js assert module\. +. +.IP "\(bu" 4 +Simple to use +. +.IP "\(bu" 4 +Just export the tests from a module +. +.IP "\(bu" 4 +Helps you avoid common pitfalls when testing asynchronous code +. +.IP "\(bu" 4 +Easy to add test cases with setUp and tearDown functions if you wish +. +.IP "\(bu" 4 +Allows the use of mocks and stubs +. +.IP "" 0 +. +.SH "OPTIONS" + \fB\-\-config FILE\fR: +. +.br + Load config options from a JSON file, allows the customisation + of color schemes for the default test reporter etc\. + See bin/nodeunit\.json for current available options\. +. +.P + \fB\-\-reporter FILE\fR: +. +.br + You can set the test reporter to a custom module or on of the modules + in nodeunit/lib/reporters, when omitted, the default test runner is used\. +. +.P + \fB\-\-list\-reporters\fR: +. +.br + List available build\-in reporters\. +. +.P + \fB\-h\fR, \fB\-\-help\fR: +. +.br + Display the help and exit\. +. +.P + \fB\-v\fR, \fB\-\-version\fR: +. +.br + Output version information and exit\. +. +.P + \fB\fR: + You can run nodeunit on specific files or on all \fI*\.js\fR files inside +. +.br + a directory\. +. +.SH "AUTHORS" +Written by Caolan McMahon and other nodeunit contributors\. +. +.br +Contributors list: \fIhttp://github\.com/caolan/nodeunit/contributors\fR\|\. +. +.SH "REPORTING BUGS" +Report nodeunit bugs to \fIhttp://github\.com/caolan/nodeunit/issues\fR\|\. +. +.SH "COPYRIGHT" +Copyright © 2010 Caolan McMahon\. +. +.br +Nodeunit has been released under the MIT license: +. +.br +\fIhttp://github\.com/caolan/nodeunit/raw/master/LICENSE\fR\|\. +. +.SH "SEE ALSO" +node(1) diff --git a/node_modules/nodeunit/nodelint.cfg b/node_modules/nodeunit/nodelint.cfg new file mode 100644 index 00000000..457a967e --- /dev/null +++ b/node_modules/nodeunit/nodelint.cfg @@ -0,0 +1,4 @@ +var options = { + indent: 4, + onevar: false +}; diff --git a/node_modules/nodeunit/package.json b/node_modules/nodeunit/package.json new file mode 100644 index 00000000..da62137e --- /dev/null +++ b/node_modules/nodeunit/package.json @@ -0,0 +1,53 @@ +{ "name": "nodeunit" +, "description": "Easy unit testing for node.js and the browser." +, "maintainers": + [ { "name": "Caolan McMahon" + , "web": "https://github.com/caolan" + } + ] +, "contributors" : + [ { "name": "Alex Gorbatchev" + , "web": "https://github.com/alexgorbatchev" + } + , { "name": "Alex Wolfe" + , "web": "https://github.com/alexkwolfe" + } + , { "name": "Carl Fürstenberg" + , "web": "https://github.com/azatoth" + } + , { "name": "Gerad Suyderhoud" + , "web": "https://github.com/gerad" + } + , { "name": "Kadir Pekel" + , "web": "https://github.com/coffeemate" + } + , { "name": "Oleg Efimov" + , "web": "https://github.com/Sannis" + } + , { "name": "Orlando Vazquez" + , "web": "https://github.com/orlandov" + } + , { "name": "Ryan Dahl" + , "web": "https://github.com/ry" + } + , { "name": "Sam Stephenson" + , "web": "https://github.com/sstephenson" + } + , { "name": "Thomas Mayfield" + , "web": "https://github.com/thegreatape" + } + ] +, "version": "0.5.1" +, "repository" : + { "type" : "git" + , "url" : "http://github.com/caolan/nodeunit.git" + } +, "bugs" : { "web" : "http://github.com/caolan/nodeunit/issues" } +, "licenses" : + [ { "type" : "MIT" + , "url" : "http://github.com/caolan/nodeunit/raw/master/LICENSE" + } + ] +, "directories" : { "lib": "./lib", "doc" : "./doc", "man" : "./man1" } +, "bin" : { "nodeunit" : "./bin/nodeunit" } +} diff --git a/node_modules/nodeunit/share/junit.xml.ejs b/node_modules/nodeunit/share/junit.xml.ejs new file mode 100644 index 00000000..c1db5bbe --- /dev/null +++ b/node_modules/nodeunit/share/junit.xml.ejs @@ -0,0 +1,19 @@ + +<% for (var i=0; i < suites.length; i++) { %> + <% var suite=suites[i]; %> + + <% for (var j=0; j < suite.testcases.length; j++) { %> + <% var testcase=suites[i].testcases[j]; %> + + <% if (testcase.failure) { %> + + <% if (testcase.failure.backtrace) { %><%= testcase.failure.backtrace %><% } %> + + <% } %> + + <% } %> + +<% } %> diff --git a/node_modules/nodeunit/share/license.js b/node_modules/nodeunit/share/license.js new file mode 100644 index 00000000..f0f326f3 --- /dev/null +++ b/node_modules/nodeunit/share/license.js @@ -0,0 +1,11 @@ +/*! + * Nodeunit + * https://github.com/caolan/nodeunit + * Copyright (c) 2010 Caolan McMahon + * MIT Licensed + * + * json2.js + * http://www.JSON.org/json2.js + * Public Domain. + * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + */ diff --git a/node_modules/nodeunit/share/nodeunit.css b/node_modules/nodeunit/share/nodeunit.css new file mode 100644 index 00000000..274434a4 --- /dev/null +++ b/node_modules/nodeunit/share/nodeunit.css @@ -0,0 +1,70 @@ +/*! + * Styles taken from qunit.css + */ + +h1#nodeunit-header, h1.nodeunit-header { + padding: 15px; + font-size: large; + background-color: #06b; + color: white; + font-family: 'trebuchet ms', verdana, arial; + margin: 0; +} + +h1#nodeunit-header a { + color: white; +} + +h2#nodeunit-banner { + height: 2em; + border-bottom: 1px solid white; + background-color: #eee; + margin: 0; + font-family: 'trebuchet ms', verdana, arial; +} +h2#nodeunit-banner.pass { + background-color: green; +} +h2#nodeunit-banner.fail { + background-color: red; +} + +h2#nodeunit-userAgent, h2.nodeunit-userAgent { + padding: 10px; + background-color: #eee; + color: black; + margin: 0; + font-size: small; + font-weight: normal; + font-family: 'trebuchet ms', verdana, arial; + font-size: 10pt; +} + +div#nodeunit-testrunner-toolbar { + background: #eee; + border-top: 1px solid black; + padding: 10px; + font-family: 'trebuchet ms', verdana, arial; + margin: 0; + font-size: 10pt; +} + +ol#nodeunit-tests { + font-family: 'trebuchet ms', verdana, arial; + font-size: 10pt; +} +ol#nodeunit-tests li strong { + cursor:pointer; +} +ol#nodeunit-tests .pass { + color: green; +} +ol#nodeunit-tests .fail { + color: red; +} + +p#nodeunit-testresult { + margin-left: 1em; + font-size: 10pt; + font-family: 'trebuchet ms', verdana, arial; +} diff --git a/node_modules/nodeunit/test/fixtures/coffee/mock_coffee_module.coffee b/node_modules/nodeunit/test/fixtures/coffee/mock_coffee_module.coffee new file mode 100644 index 00000000..a1c069b5 --- /dev/null +++ b/node_modules/nodeunit/test/fixtures/coffee/mock_coffee_module.coffee @@ -0,0 +1,4 @@ +j = 0 +j += i for i in [0..5] + +exports.name = "mock_coffee_#{j}" diff --git a/node_modules/nodeunit/test/fixtures/dir/mock_module3.js b/node_modules/nodeunit/test/fixtures/dir/mock_module3.js new file mode 100644 index 00000000..3021776c --- /dev/null +++ b/node_modules/nodeunit/test/fixtures/dir/mock_module3.js @@ -0,0 +1 @@ +exports.name = 'mock_module3'; diff --git a/node_modules/nodeunit/test/fixtures/dir/mock_module4.js b/node_modules/nodeunit/test/fixtures/dir/mock_module4.js new file mode 100644 index 00000000..876f9ca0 --- /dev/null +++ b/node_modules/nodeunit/test/fixtures/dir/mock_module4.js @@ -0,0 +1 @@ +exports.name = 'mock_module4'; diff --git a/node_modules/nodeunit/test/fixtures/mock_module1.js b/node_modules/nodeunit/test/fixtures/mock_module1.js new file mode 100644 index 00000000..4c093ad1 --- /dev/null +++ b/node_modules/nodeunit/test/fixtures/mock_module1.js @@ -0,0 +1 @@ +exports.name = 'mock_module1'; diff --git a/node_modules/nodeunit/test/fixtures/mock_module2.js b/node_modules/nodeunit/test/fixtures/mock_module2.js new file mode 100644 index 00000000..a63d0122 --- /dev/null +++ b/node_modules/nodeunit/test/fixtures/mock_module2.js @@ -0,0 +1 @@ +exports.name = 'mock_module2'; diff --git a/node_modules/nodeunit/test/fixtures/raw_jscode1.js b/node_modules/nodeunit/test/fixtures/raw_jscode1.js new file mode 100644 index 00000000..2ef71152 --- /dev/null +++ b/node_modules/nodeunit/test/fixtures/raw_jscode1.js @@ -0,0 +1,3 @@ +function hello_world(arg) { + return "_" + arg + "_"; +} diff --git a/node_modules/nodeunit/test/fixtures/raw_jscode2.js b/node_modules/nodeunit/test/fixtures/raw_jscode2.js new file mode 100644 index 00000000..55a764ef --- /dev/null +++ b/node_modules/nodeunit/test/fixtures/raw_jscode2.js @@ -0,0 +1,3 @@ +function get_a_variable() { + return typeof a_variable; +} diff --git a/node_modules/nodeunit/test/fixtures/raw_jscode3.js b/node_modules/nodeunit/test/fixtures/raw_jscode3.js new file mode 100644 index 00000000..1fd1e788 --- /dev/null +++ b/node_modules/nodeunit/test/fixtures/raw_jscode3.js @@ -0,0 +1 @@ +var t=t?t+1:1; diff --git a/node_modules/nodeunit/test/test-base.js b/node_modules/nodeunit/test/test-base.js new file mode 100644 index 00000000..64b8c8bb --- /dev/null +++ b/node_modules/nodeunit/test/test-base.js @@ -0,0 +1,219 @@ +/* + * This module is not a plain nodeunit test suite, but instead uses the + * assert module to ensure a basic level of functionality is present, + * allowing the rest of the tests to be written using nodeunit itself. + * + * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! + * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. + * Only code on that line will be removed, its mostly to avoid requiring code + * that is node specific + */ + +var assert = require('assert'), // @REMOVE_LINE_FOR_BROWSER + async = require('../deps/async'), // @REMOVE_LINE_FOR_BROWSER + nodeunit = require('../lib/nodeunit'); // @REMOVE_LINE_FOR_BROWSER + + +// NOT A TEST - util function to make testing faster. +// retries the assertion until it passes or the timeout is reached, +// at which point it throws the assertion error +var waitFor = function (fn, timeout, callback, start) { + start = start || new Date().getTime(); + callback = callback || function () {}; + try { + fn(); + callback(); + } + catch (e) { + if (e instanceof assert.AssertionError) { + var now = new Date().getTime(); + if (now - start >= timeout) { + throw e; + } + else { + async.nextTick(function () { + waitFor(fn, timeout, callback, start); + }); + } + } + else { + throw e; + } + } +}; + + +// TESTS: + +// Are exported tests actually run? - store completed tests in this variable +// for checking later +var tests_called = {}; + +// most basic test that should run, the tests_called object is tested +// at the end of this module to ensure the tests were actually run by nodeunit +exports.testCalled = function (test) { + tests_called.testCalled = true; + test.done(); +}; + +// generates test functions for nodeunit assertions +var makeTest = function (method, args_pass, args_fail) { + return function (test) { + var test1_called = false; + var test2_called = false; + + // test pass + nodeunit.runTest( + 'testname', + function (test) { + test[method].apply(test, args_pass); + test.done(); + }, + {testDone: function (name, assertions) { + assert.equal(assertions.length, 1); + assert.equal(assertions.failures(), 0); + }}, + function () { + test1_called = true; + } + ); + + // test failure + nodeunit.runTest( + 'testname', + function (test) { + test[method].apply(test, args_fail); + test.done(); + }, + {testDone: function (name, assertions) { + assert.equal(assertions.length, 1); + assert.equal(assertions.failures(), 1); + }}, + function () { + test2_called = true; + } + ); + + // ensure tests were run + waitFor(function () { + assert.ok(test1_called); + assert.ok(test2_called); + tests_called[method] = true; + }, 500, test.done); + }; +}; + +// ensure basic assertions are working: +exports.testOk = makeTest('ok', [true], [false]); +exports.testEquals = makeTest('equals', [1, 1], [1, 2]); +exports.testSame = makeTest('same', + [{test: 'test'}, {test: 'test'}], + [{test: 'test'}, {monkey: 'penguin'}] +); + +// from the assert module: +exports.testEqual = makeTest('equal', [1, 1], [1, 2]); +exports.testNotEqual = makeTest('notEqual', [1, 2], [1, 1]); +exports.testDeepEqual = makeTest('deepEqual', + [{one: 1}, {one: 1}], [{one: 1}, {two: 2}] +); +exports.testNotDeepEqual = makeTest('notDeepEqual', + [{one: 1}, {two: 2}], [{one: 1}, {one: 1}] +); +exports.testStrictEqual = makeTest('strictEqual', [1, 1], [1, true]); +exports.testNotStrictEqual = makeTest('notStrictEqual', [true, 1], [1, 1]); +exports.testThrows = makeTest('throws', + [function () { + throw new Error('test'); + }], + [function () { + return; + }] +); +exports.testDoesNotThrows = makeTest('doesNotThrow', + [function () { + return; + }], + [function () { + throw new Error('test'); + }] +); +exports.testIfError = makeTest('ifError', [false], [new Error('test')]); + + +exports.testExpect = function (test) { + var test1_called = false, + test2_called = false, + test3_called = false; + + // correct number of tests run + nodeunit.runTest( + 'testname', + function (test) { + test.expect(2); + test.ok(true); + test.ok(true); + test.done(); + }, + {testDone: function (name, assertions) { + test.equals(assertions.length, 2); + test.equals(assertions.failures(), 0); + }}, + function () { + test1_called = true; + } + ); + + // no tests run + nodeunit.runTest( + 'testname', + function (test) { + test.expect(2); + test.done(); + }, + {testDone: function (name, assertions) { + test.equals(assertions.length, 1); + test.equals(assertions.failures(), 1); + }}, + function () { + test2_called = true; + } + ); + + // incorrect number of tests run + nodeunit.runTest( + 'testname', + function (test) { + test.expect(2); + test.ok(true); + test.ok(true); + test.ok(true); + test.done(); + }, + {testDone: function (name, assertions) { + test.equals(assertions.length, 4); + test.equals(assertions.failures(), 1); + }}, + function () { + test3_called = true; + } + ); + + // ensure callbacks fired + waitFor(function () { + assert.ok(test1_called); + assert.ok(test2_called); + assert.ok(test3_called); + tests_called.expect = true; + }, 500, test.done); +}; + + +// tests are async, so wait for them to be called +waitFor(function () { + assert.ok(tests_called.testCalled); + assert.ok(tests_called.ok); + assert.ok(tests_called.equals); + assert.ok(tests_called.same); + assert.ok(tests_called.expect); +}, 10000); diff --git a/node_modules/nodeunit/test/test-failing-callbacks.js b/node_modules/nodeunit/test/test-failing-callbacks.js new file mode 100644 index 00000000..08f7eb58 --- /dev/null +++ b/node_modules/nodeunit/test/test-failing-callbacks.js @@ -0,0 +1,114 @@ +var nodeunit = require('../lib/nodeunit'); + + +exports.testFailingLog = function (test) { + test.expect(3); + + // this is meant to bubble to the top, and will be ignored for the purposes + // of testing: + var ignored_error = new Error('ignore this callback error'); + var err_handler = function (err) { + if (err && err.message !== ignored_error.message) { + throw err; + } + }; + process.addListener('uncaughtException', err_handler); + + // A failing callback should not affect the test outcome + var testfn = function (test) { + test.ok(true, 'test.ok'); + test.done(); + }; + nodeunit.runTest('testname', testfn, { + log: function (assertion) { + test.ok(true, 'log called'); + throw ignored_error; + }, + testDone: function (name, assertions) { + test.equals(assertions.failures(), 0, 'failures'); + test.equals(assertions.length, 1, 'total'); + process.removeListener('uncaughtException', err_handler); + } + }, test.done); +}; + +exports.testFailingTestDone = function (test) { + test.expect(2); + + var ignored_error = new Error('ignore this callback error'); + var err_handler = function (err) { + if (err && err.message !== ignored_error.message) { + throw err; + } + }; + process.addListener('uncaughtException', err_handler); + + // A failing callback should not affect the test outcome + var testfn = function (test) { + test.done(); + }; + nodeunit.runTest('testname', testfn, { + log: function (assertion) { + test.ok(false, 'log should not be called'); + }, + testDone: function (name, assertions) { + test.equals(assertions.failures(), 0, 'failures'); + test.equals(assertions.length, 0, 'total'); + process.nextTick(function () { + process.removeListener('uncaughtException', err_handler); + test.done(); + }); + throw ignored_error; + } + }, function () {}); +}; + +exports.testAssertionObj = function (test) { + test.expect(4); + var testfn = function (test) { + test.ok(true, 'ok true'); + test.done(); + }; + nodeunit.runTest('testname', testfn, { + log: function (assertion) { + test.ok(assertion.passed() === true, 'assertion.passed'); + test.ok(assertion.failed() === false, 'assertion.failed'); + }, + testDone: function (name, assertions) { + test.equals(assertions.failures(), 0, 'failures'); + test.equals(assertions.length, 1, 'total'); + } + }, test.done); +}; + +exports.testLogOptional = function (test) { + test.expect(2); + var testfn = function (test) { + test.ok(true, 'ok true'); + test.done(); + }; + nodeunit.runTest('testname', testfn, { + testDone: function (name, assertions) { + test.equals(assertions.failures(), 0, 'failures'); + test.equals(assertions.length, 1, 'total'); + } + }, test.done); +}; + +exports.testExpectWithFailure = function (test) { + test.expect(3); + var testfn = function (test) { + test.expect(1); + test.ok(false, 'test.ok'); + test.done(); + }; + nodeunit.runTest('testname', testfn, { + log: function (assertion) { + test.equals(assertion.method, 'ok', 'assertion.method'); + }, + testDone: function (name, assertions) { + test.equals(assertions.failures(), 1, 'failures'); + test.equals(assertions.length, 1, 'total'); + } + }, test.done); +}; diff --git a/node_modules/nodeunit/test/test-httputil.js b/node_modules/nodeunit/test/test-httputil.js new file mode 100644 index 00000000..e5ee25c6 --- /dev/null +++ b/node_modules/nodeunit/test/test-httputil.js @@ -0,0 +1,55 @@ +var nodeunit = require('../lib/nodeunit'); +var httputil = require('../lib/utils').httputil; + +exports.testHttpUtilBasics = function (test) { + + test.expect(6); + + httputil(function (req, resp) { + test.equal(req.method, 'PUT'); + test.equal(req.url, '/newpair'); + test.equal(req.headers.foo, 'bar'); + + resp.writeHead(500, {'content-type': 'text/plain'}); + resp.end('failed'); + }, function (server, client) { + client.fetch('PUT', '/newpair', {'foo': 'bar'}, function (resp) { + test.equal(resp.statusCode, 500); + test.equal(resp.headers['content-type'], 'text/plain'); + test.equal(resp.body, 'failed'); + + server.close(); + test.done(); + }); + }); +}; + +exports.testHttpUtilJsonHandling = function (test) { + + test.expect(9); + + httputil(function (req, resp) { + test.equal(req.method, 'GET'); + test.equal(req.url, '/'); + test.equal(req.headers.foo, 'bar'); + + var testdata = {foo1: 'bar', foo2: 'baz'}; + + resp.writeHead(200, {'content-type': 'application/json'}); + resp.end(JSON.stringify(testdata)); + + }, function (server, client) { + client.fetch('GET', '/', {'foo': 'bar'}, function (resp) { + test.equal(resp.statusCode, 200); + test.equal(resp.headers['content-type'], 'application/json'); + + test.ok(resp.bodyAsObject); + test.equal(typeof resp.bodyAsObject, 'object'); + test.equal(resp.bodyAsObject.foo1, 'bar'); + test.equal(resp.bodyAsObject.foo2, 'baz'); + + server.close(); + test.done(); + }); + }); +}; diff --git a/node_modules/nodeunit/test/test-runfiles.js b/node_modules/nodeunit/test/test-runfiles.js new file mode 100644 index 00000000..b9ef754f --- /dev/null +++ b/node_modules/nodeunit/test/test-runfiles.js @@ -0,0 +1,214 @@ +var assert = require('assert'), + sys = require('sys'), + fs = require('fs'), + path = require('path'), + nodeunit = require('../lib/nodeunit'); + + +var setup = function (fn) { + return function (test) { + process.chdir(__dirname); + require.paths.push(__dirname); + var env = { + mock_module1: require('./fixtures/mock_module1'), + mock_module2: require('./fixtures/mock_module2'), + mock_module3: require('./fixtures/dir/mock_module3'), + mock_module4: require('./fixtures/dir/mock_module4') + }; + fn.call(env, test); + }; +}; + + +exports.testRunFiles = setup(function (test) { + test.expect(24); + var runModule_copy = nodeunit.runModule; + + var runModule_calls = []; + var modules = []; + + var opts = { + moduleStart: function () { + return 'moduleStart'; + }, + testDone: function () { + return 'testDone'; + }, + testStart: function () { + return 'testStart'; + }, + log: function () { + return 'log'; + }, + done: function (assertions) { + test.equals(assertions.failures(), 0, 'failures'); + test.equals(assertions.length, 4, 'length'); + test.ok(typeof assertions.duration === "number"); + + var called_with = function (name) { + return runModule_calls.some(function (m) { + return m.name === name; + }); + }; + test.ok(called_with('mock_module1'), 'mock_module1 ran'); + test.ok(called_with('mock_module2'), 'mock_module2 ran'); + test.ok(called_with('mock_module3'), 'mock_module3 ran'); + test.ok(called_with('mock_module4'), 'mock_module4 ran'); + test.equals(runModule_calls.length, 4); + + nodeunit.runModule = runModule_copy; + test.done(); + } + }; + + nodeunit.runModule = function (name, mod, options, callback) { + test.equals(options.testDone, opts.testDone); + test.equals(options.testStart, opts.testStart); + test.equals(options.log, opts.log); + test.ok(typeof name === "string"); + runModule_calls.push(mod); + var m = [{failed: function () { + return false; + }}]; + modules.push(m); + callback(null, m); + }; + + nodeunit.runFiles( + ['fixtures/mock_module1.js', 'fixtures/mock_module2.js', 'fixtures/dir'], + opts + ); +}); + +exports.testRunFilesEmpty = function (test) { + test.expect(3); + nodeunit.runFiles([], { + moduleStart: function () { + test.ok(false, 'should not be called'); + }, + testDone: function () { + test.ok(false, 'should not be called'); + }, + testStart: function () { + test.ok(false, 'should not be called'); + }, + log: function () { + test.ok(false, 'should not be called'); + }, + done: function (assertions) { + test.equals(assertions.failures(), 0, 'failures'); + test.equals(assertions.length, 0, 'length'); + test.ok(typeof assertions.duration === "number"); + test.done(); + } + }); +}; + + +exports.testEmptyDir = function (test) { + var dir2 = __dirname + '/fixtures/dir2'; + + // git doesn't like empty directories, so we have to create one + path.exists(dir2, function (exists) { + if (!exists) { + fs.mkdirSync(dir2, 0777); + } + + // runFiles on empty directory: + nodeunit.runFiles([dir2], { + moduleStart: function () { + test.ok(false, 'should not be called'); + }, + testDone: function () { + test.ok(false, 'should not be called'); + }, + testStart: function () { + test.ok(false, 'should not be called'); + }, + log: function () { + test.ok(false, 'should not be called'); + }, + done: function (assertions) { + test.equals(assertions.failures(), 0, 'failures'); + test.equals(assertions.length, 0, 'length'); + test.ok(typeof assertions.duration === "number"); + test.done(); + } + }); + }); +}; + + +var CoffeeScript; +try { + CoffeeScript = require('coffee-script'); +} catch (e) { +} + +if (CoffeeScript) { + exports.testCoffeeScript = function (test) { + process.chdir(__dirname); + require.paths.push(__dirname); + var env = { + mock_coffee_module: require('./fixtures/coffee/mock_coffee_module') + }; + + test.expect(9); + var runModule_copy = nodeunit.runModule; + + var runModule_calls = []; + var modules = []; + + var opts = { + moduleStart: function () { + return 'moduleStart'; + }, + testDone: function () { + return 'testDone'; + }, + testStart: function () { + return 'testStart'; + }, + log: function () { + return 'log'; + }, + done: function (assertions) { + test.equals(assertions.failures(), 0, 'failures'); + test.equals(assertions.length, 1, 'length'); + test.ok(typeof assertions.duration === "number"); + + var called_with = function (name) { + return runModule_calls.some(function (m) { + return m.name === name; + }); + }; + test.ok( + called_with('mock_coffee_15'), + 'mock_coffee_module ran' + ); + test.equals(runModule_calls.length, 1); + + nodeunit.runModule = runModule_copy; + test.done(); + } + }; + + nodeunit.runModule = function (name, mod, options, callback) { + test.equals(options.testDone, opts.testDone); + test.equals(options.testStart, opts.testStart); + test.equals(options.log, opts.log); + test.ok(typeof name === "string"); + runModule_calls.push(mod); + var m = [{failed: function () { + return false; + }}]; + modules.push(m); + callback(null, m); + }; + + nodeunit.runFiles( + ['fixtures/coffee/mock_coffee_module.coffee'], + opts + ); + }; +} diff --git a/node_modules/nodeunit/test/test-runmodule.js b/node_modules/nodeunit/test/test-runmodule.js new file mode 100644 index 00000000..218e8dbe --- /dev/null +++ b/node_modules/nodeunit/test/test-runmodule.js @@ -0,0 +1,125 @@ +/* THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! + * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. + * Only code on that line will be removed, its mostly to avoid requiring code + * that is node specific + */ + +var nodeunit = require('../lib/nodeunit'); // @REMOVE_LINE_FOR_BROWSER + + +exports.testRunModule = function (test) { + test.expect(11); + var call_order = []; + var testmodule = { + test1: function (test) { + call_order.push('test1'); + test.ok(true, 'ok true'); + test.done(); + }, + test2: function (test) { + call_order.push('test2'); + test.ok(false, 'ok false'); + test.ok(false, 'ok false'); + test.done(); + }, + test3: function (test) { + call_order.push('test3'); + test.done(); + } + }; + nodeunit.runModule('testmodule', testmodule, { + log: function (assertion) { + call_order.push('log'); + }, + testStart: function (name) { + call_order.push('testStart'); + test.ok( + name.toString() === 'test1' || + name.toString() === 'test2' || + name.toString() === 'test3', + 'testStart called with test name ' + ); + }, + testDone: function (name, assertions) { + call_order.push('testDone'); + test.ok( + name.toString() === 'test1' || + name.toString() === 'test2' || + name.toString() === 'test3', + 'testDone called with test name' + ); + }, + moduleDone: function (name, assertions) { + call_order.push('moduleDone'); + test.equals(assertions.length, 3); + test.equals(assertions.failures(), 2); + test.equals(name, 'testmodule'); + test.ok(typeof assertions.duration === "number"); + test.same(call_order, [ + 'testStart', 'test1', 'log', 'testDone', + 'testStart', 'test2', 'log', 'log', 'testDone', + 'testStart', 'test3', 'testDone', + 'moduleDone' + ]); + } + }, test.done); +}; + +exports.testRunModuleEmpty = function (test) { + nodeunit.runModule('module with no exports', {}, { + log: function (assertion) { + test.ok(false, 'log should not be called'); + }, + testStart: function (name) { + test.ok(false, 'testStart should not be called'); + }, + testDone: function (name, assertions) { + test.ok(false, 'testDone should not be called'); + }, + moduleDone: function (name, assertions) { + test.equals(assertions.length, 0); + test.equals(assertions.failures(), 0); + test.equals(name, 'module with no exports'); + test.ok(typeof assertions.duration === "number"); + } + }, test.done); +}; + +exports.testNestedTests = function (test) { + var call_order = []; + var m = { + test1: function (test) { + test.done(); + }, + suite: { + t1: function (test) { + test.done(); + }, + t2: function (test) { + test.done(); + }, + another_suite: { + t3: function (test) { + test.done(); + } + } + } + }; + nodeunit.runModule('modulename', m, { + testStart: function (name) { + call_order.push(['testStart'].concat(name)); + }, + testDone: function (name, assertions) { + call_order.push(['testDone'].concat(name)); + } + }, function () { + test.same(call_order, [ + ['testStart', 'test1'], ['testDone', 'test1'], + ['testStart', 'suite', 't1'], ['testDone', 'suite', 't1'], + ['testStart', 'suite', 't2'], ['testDone', 'suite', 't2'], + ['testStart', 'suite', 'another_suite', 't3'], + ['testDone', 'suite', 'another_suite', 't3'] + ]); + test.done(); + }); +}; diff --git a/node_modules/nodeunit/test/test-runtest.js b/node_modules/nodeunit/test/test-runtest.js new file mode 100644 index 00000000..8fc3d520 --- /dev/null +++ b/node_modules/nodeunit/test/test-runtest.js @@ -0,0 +1,46 @@ +/* THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! + * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. + * Only code on that line will be removed, its mostly to avoid requiring code + * that is node specific + */ + +var nodeunit = require('../lib/nodeunit'); // @REMOVE_LINE_FOR_BROWSER + + +exports.testArgs = function (test) { + test.ok(test.expect instanceof Function, 'test.expect'); + test.ok(test.done instanceof Function, 'test.done'); + test.ok(test.ok instanceof Function, 'test.ok'); + test.ok(test.same instanceof Function, 'test.same'); + test.ok(test.equals instanceof Function, 'test.equals'); + test.done(); +}; + +exports.testDoneCallback = function (test) { + test.expect(4); + nodeunit.runTest('testname', exports.testArgs, { + testDone: function (name, assertions) { + test.equals(assertions.failures(), 0, 'failures'); + test.equals(assertions.length, 5, 'length'); + test.ok(typeof assertions.duration === "number"); + test.equals(name, 'testname'); + } + }, test.done); +}; + +exports.testThrowError = function (test) { + test.expect(3); + var err = new Error('test'); + var testfn = function (test) { + throw err; + }; + nodeunit.runTest('testname', testfn, { + log: function (assertion) { + test.same(assertion.error, err, 'assertion.error'); + }, + testDone: function (name, assertions) { + test.equals(assertions.failures(), 1); + test.equals(assertions.length, 1); + } + }, test.done); +}; diff --git a/node_modules/nodeunit/test/test-sandbox.js b/node_modules/nodeunit/test/test-sandbox.js new file mode 100644 index 00000000..1b249d7a --- /dev/null +++ b/node_modules/nodeunit/test/test-sandbox.js @@ -0,0 +1,31 @@ +var nodeunit = require('../lib/nodeunit'); +var sandbox = require('../lib/utils').sandbox; +var testCase = nodeunit.testCase; + +exports.testSimpleSandbox = function (test) { + var raw_jscode1 = sandbox(__dirname + '/fixtures/raw_jscode1.js'); + test.equal(raw_jscode1.hello_world('foo'), '_foo_', 'evaluation ok'); + test.done(); +}; + +exports.testSandboxContext = function (test) { + var a_variable = 42; // should not be visible in the sandbox + var raw_jscode2 = sandbox(__dirname + '/fixtures/raw_jscode2.js'); + a_variable = 42; // again for the win + test.equal( + raw_jscode2.get_a_variable(), + 'undefined', + 'the variable should not be defined' + ); + test.done(); +}; + +exports.testSandboxMultiple = function (test) { + var raw_jscode3 = sandbox([ + __dirname + '/fixtures/raw_jscode3.js', + __dirname + '/fixtures/raw_jscode3.js', + __dirname + '/fixtures/raw_jscode3.js' + ]); + test.equal(raw_jscode3.t, 3, 'two files loaded'); + test.done(); +}; diff --git a/node_modules/nodeunit/test/test-testcase.js b/node_modules/nodeunit/test/test-testcase.js new file mode 100644 index 00000000..a3ea331b --- /dev/null +++ b/node_modules/nodeunit/test/test-testcase.js @@ -0,0 +1,234 @@ +/* THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! + * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. + * Only code on that line will be removed, its mostly to avoid requiring code + * that is node specific + */ + +var nodeunit = require('../lib/nodeunit'); // @REMOVE_LINE_FOR_BROWSER +var testCase = nodeunit.testCase; + +exports.testTestCase = function (test) { + test.expect(7); + var call_order = []; + var s = testCase({ + setUp: function (callback) { + call_order.push('setUp'); + test.equals(this.one, undefined); + this.one = 1; + callback(); + }, + tearDown: function (callback) { + call_order.push('tearDown'); + test.ok(true, 'tearDown called'); + callback(); + }, + test1: function (t) { + call_order.push('test1'); + test.equals(this.one, 1); + this.one = 2; + t.done(); + }, + test2: function (t) { + call_order.push('test2'); + test.equals(this.one, 1); + t.done(); + } + }); + nodeunit.runSuite(null, s, {}, function () { + test.same(call_order, [ + 'setUp', 'test1', 'tearDown', + 'setUp', 'test2', 'tearDown' + ]); + test.done(); + }); +}; + +exports.tearDownAfterError = function (test) { + test.expect(1); + var s = testCase({ + tearDown: function (callback) { + test.ok(true, 'tearDown called'); + callback(); + }, + test: function (t) { + throw new Error('some error'); + } + }); + nodeunit.runSuite(null, s, {}, function () { + test.done(); + }); +}; + +exports.catchSetUpError = function (test) { + test.expect(2); + var test_error = new Error('test error'); + var s = testCase({ + setUp: function (callback) { + throw test_error; + }, + test: function (t) { + test.ok(false, 'test function should not be called'); + t.done(); + } + }); + nodeunit.runSuite(null, s, {}, function (err, assertions) { + test.equal(assertions.length, 1); + test.equal(assertions[0].error, test_error); + test.done(); + }); +}; + +exports.setUpErrorCallback = function (test) { + test.expect(2); + var test_error = new Error('test error'); + var s = testCase({ + setUp: function (callback) { + callback(test_error); + }, + test: function (t) { + test.ok(false, 'test function should not be called'); + t.done(); + } + }); + nodeunit.runSuite(null, s, {}, function (err, assertions) { + test.equal(assertions.length, 1); + test.equal(assertions[0].error, test_error); + test.done(); + }); +}; + +exports.catchTearDownError = function (test) { + test.expect(2); + var test_error = new Error('test error'); + var s = testCase({ + tearDown: function (callback) { + throw test_error; + }, + test: function (t) { + t.done(); + } + }); + nodeunit.runSuite(null, s, {}, function (err, assertions) { + test.equal(assertions.length, 1); + test.equal(assertions[0].error, test_error); + test.done(); + }); +}; + +exports.tearDownErrorCallback = function (test) { + test.expect(2); + var test_error = new Error('test error'); + var s = testCase({ + tearDown: function (callback) { + callback(test_error); + }, + test: function (t) { + t.done(); + } + }); + nodeunit.runSuite(null, s, {}, function (err, assertions) { + test.equal(assertions.length, 1); + test.equal(assertions[0].error, test_error); + test.done(); + }); +}; + +exports.testErrorAndtearDownError = function (test) { + test.expect(3); + var error1 = new Error('test error one'); + var error2 = new Error('test error two'); + var s = testCase({ + tearDown: function (callback) { + callback(error2); + }, + test: function (t) { + t.done(error1); + } + }); + nodeunit.runSuite(null, s, {}, function (err, assertions) { + test.equal(assertions.length, 2); + test.equal(assertions[0].error, error1); + test.equal(assertions[1].error, error2); + test.done(); + }); +}; + +exports.testCaseGroups = function (test) { + var call_order = []; + var s = testCase({ + setUp: function (callback) { + call_order.push('setUp'); + callback(); + }, + tearDown: function (callback) { + call_order.push('tearDown'); + callback(); + }, + test1: function (test) { + call_order.push('test1'); + test.done(); + }, + group1: { + test2: function (test) { + call_order.push('group1.test2'); + test.done(); + } + } + }); + nodeunit.runSuite(null, s, {}, function (err, assertions) { + test.same(call_order, [ + 'setUp', + 'test1', + 'tearDown', + 'setUp', + 'group1.test2', + 'tearDown' + ]); + test.done(); + }); +}; + +exports.nestedTestCases = function (test) { + var call_order = []; + var s = testCase({ + setUp: function (callback) { + call_order.push('setUp'); + callback(); + }, + tearDown: function (callback) { + call_order.push('tearDown'); + callback(); + }, + test1: function (test) { + call_order.push('test1'); + test.done(); + }, + group1: testCase({ + setUp: function (callback) { + call_order.push('group1.setUp'); + callback(); + }, + tearDown: function (callback) { + call_order.push('group1.tearDown'); + callback(); + }, + test2: function (test) { + call_order.push('group1.test2'); + test.done(); + } + }) + }); + nodeunit.runSuite(null, s, {}, function (err, assertions) { + test.same(call_order, [ + 'setUp', + 'test1', + 'tearDown', + 'setUp', + 'group1.setUp', + 'group1.test2', + 'group1.tearDown', + 'tearDown' + ]); + test.done(); + }); +}; diff --git a/node_modules/nodeunit/test/test.html b/node_modules/nodeunit/test/test.html new file mode 100644 index 00000000..31bda305 --- /dev/null +++ b/node_modules/nodeunit/test/test.html @@ -0,0 +1,26 @@ + + + Nodeunit Test Suite + + + + + + + + + +

    Nodeunit Test Suite

    + + + diff --git a/node_modules/signals/.gitignore b/node_modules/signals/.gitignore new file mode 100644 index 00000000..c91a73ad --- /dev/null +++ b/node_modules/signals/.gitignore @@ -0,0 +1,8 @@ +.tmp* +.project +.settings/ + +.DS_Store? +ehthumbs.db +Icon? +Thumbs.db \ No newline at end of file diff --git a/node_modules/signals/.npmignore b/node_modules/signals/.npmignore new file mode 100644 index 00000000..826dec5d --- /dev/null +++ b/node_modules/signals/.npmignore @@ -0,0 +1,5 @@ +dev/ +dist/js-signals.amd.js +dist/js-signals.js +dist/js-signals.min.js +build.xml \ No newline at end of file diff --git a/node_modules/signals/CHANGELOG.markdown b/node_modules/signals/CHANGELOG.markdown new file mode 100644 index 00000000..e754bd4e --- /dev/null +++ b/node_modules/signals/CHANGELOG.markdown @@ -0,0 +1,184 @@ +# JS-Signals Changelog # + +## v0.6.1 (2011/05/03) ## + + - added NPM package.json and CommmonJS wrapper for NPM distribution. (thanks @tomyan) + + +## v0.6 (2011/04/09) ## + +### API changes ### + + - Added: + - `Signal.active` + - `SignalBinding.active` + + - Removed: + - `Signal.protytpe.enable()` + - `Signal.protytpe.disable()` + - `Signal.protytpe.isEnabled()` + - `SignalBinding.protytpe.enable()` + - `SignalBinding.protytpe.disable()` + - `SignalBinding.protytpe.isEnabled()` + +### Other ### + + - created AMD wrapped version. + - switched from "module pattern" to a closure with a global export. + + + +## v0.5.3 (2011/02/21) ## + +### API changes ### + + - added priority parameter to `add` and `addOnce`. + +### Other ### + + - improved code structure. + + + +## v0.5.2 (2011/02/18) ## + +### Other ### + + - changed to a module pattern. + - added YUI test coverage. + - improved build and src files structure. + - simplified `remove`, `removeAll`, `add`. + - improved error messages. + + + +## v0.5.1 (2011/01/30) ## + +### API changes ### + + - made `SignalBinding` constructor private. (issue #15) + - changed params order on `SignalBinding` constructor. + - removed `signals.isDef()`. (issue #14) + +### Other ### + + - added JSLint to the build process. (issue #12) + - validated source code using JSLint. (issue #13) + - improved docs. + + + +## v0.5 (2010/12/03) ## + +### API changes ### + + - Added: + - `SignalBinding.prototype.getListener()` (issue #3) + - `Signal.prototype.dispose()` (issue #6) + - `signals.VERSION` + - `signals.isDef()` + + - Removed: + - `SignalBinding.listener` (issue #3) + + - Renamed: + - `SignalBinding.listenerScope` -> `SignalBinding.context` (issue #4) + +### Fixes ### + + - Removed unnecessary function names (issue #5) + - Improved `remove()`, `removeAll()` to dispose binding (issue #10) + +### Test Changes ### + + - Added different HTML files to test dev/dist/min files. + - Updated test cases to match new API. + +### Other ### + + - Improved source code comments and documentation. + - Small refactoring for better organization and DRY. + - Added error messages for required params. + - Removed unnecessary info from `SignalBinding.toString()`. + + + +## v0.4 (2010/11/27) ## + +### API changes ### + + - Added: + - `SignalBinding.prototype.detach()` + - `SignalBinding.prototype.dispose()` + +### Test Changes ### + + - Added test cases for `detach` and `dispose`. + +### Other ### + + - Improved docs for a few methods. + - Added internal method `Signal.prototype._addBinding()`. + + + +## v0.3 (2010/11/27) ## + +### API changes ### + + - Renamed: + - `Signal.prototype.stopPropagation()` -> `Signal.prototype.halt()` + - `Signal.prototype.pause()` -> `Signal.prototype.disable()` + - `Signal.prototype.resume()` -> `Signal.prototype.enable()` + - `Signal.prototype.isPaused()` -> `Signal.prototype.isEnabled()` + - `SignalBinding.prototype.pause()` -> `SignalBinding.prototype.disable()` + - `SignalBinding.prototype.resume()` -> `SignalBinding.prototype.enable()` + - `SignalBinding.prototype.isPaused()` -> `SignalBinding.prototype.isEnabled()` + +### Fixes ### + + - Calling `halt()` before/after `dispatch()` doesn't affect listeners execution anymore, `halt()` only works during propagation. + +### Test Changes ### + + - updated API calls to reflect new method names. + - added tests that match `halt()` before/after `dispatch()`. + +### Other ### + +Added inline documentation to source code and included an HTML version of the documentation together with distribution files. + + + +## v0.2 (2010/11/26) ## + +### API changes ### + + - Added: + - `Signal.prototype.pause()` + - `Signal.prototype.resume()` + - `Signal.prototype.isPaused()` + - `Signal.prototype.stopPropagation()` + +### Fixes ### + + - `SignalBinding.prototype.isPaused()` + +### Test Changes ### + + - Increased test coverage a lot. + - Tests added: + - pause/resume (for individual bindings and signal) + - stopPropagation (using `return false` and `Signal.prototype.stopPropagation()`) + - `SignalBindings.prototype.isOnce()` + - if same listener added twice returns same binding + +### Other ### + +Small refactoring and code cleaning. + + + +## v0.1 (2010/11/26) ## + + - initial release, support of basic features. \ No newline at end of file diff --git a/node_modules/signals/README.markdown b/node_modules/signals/README.markdown new file mode 100644 index 00000000..6ab0d839 --- /dev/null +++ b/node_modules/signals/README.markdown @@ -0,0 +1,64 @@ + +# JS-Signals # + +Custom event/messaging system for JavaScript inspired by [AS3-Signals](https://github.com/robertpenner/as3-signals). + +For a more in-depth introduction read the [JS-Signals Project Page](http://millermedeiros.github.com/js-signals/) and visit the links below. + + +## Links ## + + * [Project Page](http://millermedeiros.github.com/js-signals/) + * [Wiki](http://github.com/millermedeiros/js-signals/wiki/) + * [Documentation](http://millermedeiros.github.com/js-signals/docs) + * [Changelog](http://github.com/millermedeiros/js-signals/blob/master/CHANGELOG.markdown) + + +## License ## + + * [MIT License](http://www.opensource.org/licenses/mit-license.php) + + +## Distribution Files ## + +Files inside `dist` folder. + + * docs/index.html : Documentation. + * js-signals.js : Uncompressed source code with comments. + * js-signals.amd.js : Uncompressed source code wrapped as an [asynchronous module](http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition) to be used together with [RequireJS](http://requirejs.org/). + * js-signals.cjs.js : Uncompressed source code wrapped as an [CommonJS module](http://wiki.commonjs.org/wiki/Modules/1.1) to be used on [nodejs](http://nodejs.org/) or any other environment that supports CommonJS modules. + * js-signals.min.js : Compressed code. + +You can install JS-Signals on Node.js using [NPM](http://npmjs.org/) + + npm install signals + + +## Repository Structure ## + +### Folder Structure ### + + dev -> development files + |- build -> files used on the build process + |- src -> source files + |- tests -> unit tests + dist -> distribution files + |- docs -> documentation + +### Branches ### + + master -> always contain code from the latest stable version + release-** -> code canditate for the next stable version (alpha/beta) + develop -> main development branch (nightly) + **other** -> features/hotfixes/experimental, probably non-stable code + + +## Building your own ## + +This project uses [Apache Ant](http://ant.apache.org/) for the build process. If for some reason you need to build a custom version of JS-Signals install Ant and run: + + ant build + +This will delete all JS files inside the `dist` folder, merge/update/compress source files, validate generated code using [JSLint](http://www.jslint.com/) and copy the output to the `dist` folder. + +**IMPORTANT:** `dist` folder always contain the latest version, regular users should **not** need to run build task. \ No newline at end of file diff --git a/node_modules/signals/dist/docs/files.html b/node_modules/signals/dist/docs/files.html new file mode 100644 index 00000000..94551df7 --- /dev/null +++ b/node_modules/signals/dist/docs/files.html @@ -0,0 +1,68 @@ + + + + + + JsDoc Reference - File Index + + + + + + + + + +
    +
    + +
    + +

    Index

    + +

    Classes

    + + +
    + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Tue May 03 2011 01:07:20 GMT-0300 (BRT) + | template based on Steffen Siering jsdoc-simple. +
    + + diff --git a/node_modules/signals/dist/docs/index.html b/node_modules/signals/dist/docs/index.html new file mode 100644 index 00000000..21dedd85 --- /dev/null +++ b/node_modules/signals/dist/docs/index.html @@ -0,0 +1,92 @@ + + + + + + JsDoc Reference - Index + + + + + + + + +
    +
    + +
    + +

    Index

    + +

    Classes

    + + +
    + +
    +

    Class Index

    + + +
    + +
    + Built-In Namespace +
    +

    _global_

    + +
    + +
    + +
    + Namespace +
    +

    signals

    + Signals Namespace - Custom event/messaging system based on AS3 Signals +
    + +
    + +
    + Class +
    +

    signals.Signal

    + +
    + +
    + +
    + Class +
    +

    signals.SignalBinding

    + +
    + +
    + +
    +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Tue May 03 2011 01:07:20 GMT-0300 (BRT) + | template based on Steffen Siering jsdoc-simple. +
    + + diff --git a/node_modules/signals/dist/docs/static/default.css b/node_modules/signals/dist/docs/static/default.css new file mode 100644 index 00000000..0401aef2 --- /dev/null +++ b/node_modules/signals/dist/docs/static/default.css @@ -0,0 +1,248 @@ +/* + * based on urso jsdoc-simple template: http://github.com/urso/jsdoc-simple + * adapted by Miller Medeiros (http://millermedeiros.com/) + */ + +/* default.css */ +html{ + overflow-y:scroll; +} + +body +{ + font: 12px "Lucida Grande", Tahoma, Arial, Helvetica, sans-serif; + min-width: 1000px; + max-width: 1400px; + margin:0 auto; +} + +.header +{ + clear: both; + background-color: #ccc; +} + +a +{ + text-decoration: none; + color: #c00; + outline:none; +} + +a:active, a:focus, a:hover{ + color: #333; +} + +h1 +{ + font-size: 1.5em; + font-weight: bold; + padding: 0; + margin: 1em 0 0 .3em; +} + +hr +{ + border: none 0; + border-top: 1px solid #7F8FB1; + height: 1px; +} + +pre.code +{ + display: block; + padding: 8px; + border: 1px dashed #ccc; +} + +#header{ + /*height: 110px;*/ +} + +#index +{ + float: left; + width: 200px; + padding: 20px; +} + +#symbolList +{ + margin: 20px; + width: 200px; + float:right; +} + +#symbolList ul +{ + padding: 0; + margin: 0; + padding-left: 8px; + list-style: none; + font-size: 0.85em; +} + +#symbolList h3 +{ + margin-top:1.2em; + margin-bottom: 0.5em; +} + +#symbolList ul li +{ + padding: 0; + margin: 0; +} + +#content +{ + text-align: left; + padding:0 260px; + margin:0; +} + +.classList +{ + list-style-type: none; + padding: 0; + margin: 0 0 0 8px; + font-family: arial, sans-serif; + font-size: 1em; + overflow: auto; +} + +.classList li +{ + padding: 0; + margin: 0 0 8px 0; +} + +.summaryTable { width: 100%; } + +h1.classTitle +{ + font-size:1.7em; + line-height:1.3em; +} + +h2 { font-size: 1.1em; } +caption, div.sectionTitle +{ + background-color: #ddd; + color: #333; + font-size:1.3em; + text-align: left; + padding: 2px 6px 2px 6px; + margin-top: 1.5em; + border: 1px #ddd solid; +} + +div.sectionTitle { margin-bottom: 8px; } +.summaryTable thead { display: none; } + +.summaryTable td +{ + vertical-align: top; + padding: 4px; + border-bottom: 1px #7F8FB1 solid; + border-right: 1px #7F8FB1 solid; +} + +/*col#summaryAttributes {}*/ +.summaryTable td.attributes +{ + border-left: 1px #7F8FB1 solid; + width: 140px; + text-align: right; +} + +.fixedFont b +{ + color: #c00; +} + +td.attributes, .fixedFont +{ + line-height: 1.1em; + /* color: #002EBE; */ + font-family: "Courier New",Courier,monospace; + font-size: 1.3em; +} + +.modifiers { + float: right; + /* padding: 0 2em 0 2em; */ + padding: 0; + font-size: 0.85em; +} + +.member .description +{ + margin: 0.75em 0 0 0; + padding: 0 0.5em 0 0.5em; +} + +.summaryTable td.nameDescription +{ + text-align: left; + font-size: 1.1em; + line-height: 1.2em; +} + +.summaryTable td.nameDescription, .description +{ + line-height: 15px; + padding: 4px; + padding-left: 4px; +} + +.summaryTable { margin-bottom: 8px; } + +ul.inheritsList +{ + list-style: square; + margin-left: 20px; + padding-left: 0; +} + +.detailList { + margin-left: 20px; + line-height: 15px; +} +.detailList dt { margin-left: 20px; } + +.detailList .heading +{ + font-weight: bold; + padding-bottom: 6px; + margin-left: 0; +} + +.member +{ + border: 1px solid #ccc; + background: #f8f8ff; + margin: 1em 0 1em 0; + padding: 0.75em; +} + +.light, td.attributes, .light a:link, .light a:visited +{ + color: #777; + font-style: italic; +} + +code { + /*display: block; + margin: 1em;*/ + border: 1px solid #ccc; + padding: 2px 5px; + background: #f8f8ff; +} + +.fineprint +{ + text-align: right; + font-size: 10px; + padding:10px 0 20px; +} diff --git a/node_modules/signals/dist/docs/symbolindex.html b/node_modules/signals/dist/docs/symbolindex.html new file mode 100644 index 00000000..a76598b6 --- /dev/null +++ b/node_modules/signals/dist/docs/symbolindex.html @@ -0,0 +1,279 @@ + + + + + + JsDoc Reference - Index + + + + + + + + + + + + +
    +
    + +
    + +

    Index

    + +

    Classes

    + + +
    + +
    +

    Symbol Index

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    active + + signals.Signal#active + + signals.SignalBinding#active + +
    add + + signals.Signal#add + +
    addOnce + + signals.Signal#addOnce + +
    context + + signals.SignalBinding#context + +
    detach + + signals.SignalBinding#detach + +
    dispatch + + signals.Signal#dispatch + +
    dispose + + signals.Signal#dispose + + signals.SignalBinding#dispose + +
    execute + + signals.SignalBinding#execute + +
    getListener + + signals.SignalBinding#getListener + +
    getNumListeners + + signals.Signal#getNumListeners + +
    halt + + signals.Signal#halt + +
    isOnce + + signals.SignalBinding#isOnce + +
    remove + + signals.Signal#remove + +
    removeAll + + signals.Signal#removeAll + +
    Signal + + signals.Signal + +
    SignalBinding + + signals.SignalBinding + +
    signals + + signals + +
    toString + + signals.Signal#toString + + signals.SignalBinding#toString + +
    VERSION + + signals.VERSION + +
    +
    +
    +
    +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Tue May 03 2011 01:07:20 GMT-0300 (BRT) + | template based on Steffen Siering jsdoc-simple. +
    + + + diff --git a/node_modules/signals/dist/docs/symbols/_global_.html b/node_modules/signals/dist/docs/symbols/_global_.html new file mode 100644 index 00000000..120d6285 --- /dev/null +++ b/node_modules/signals/dist/docs/symbols/_global_.html @@ -0,0 +1,108 @@ + + + + + + + JsDoc Reference - _global_ + + + + + + + + + + + + + +
    +
    + +
    + +

    Index

    + +

    Classes

    + + +
    + +
    + + + + + + + + + + + + + + + + + + +
    + +
    + +

    + Built-In Namespace _global_ +

    + + +

    + + + + + + +

    + + + + + + + + + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Tue May 03 2011 01:07:19 GMT-0300 (BRT) + | template based on Steffen Siering jsdoc-simple. +
    + + diff --git a/node_modules/signals/dist/docs/symbols/signals.Signal.html b/node_modules/signals/dist/docs/symbols/signals.Signal.html new file mode 100644 index 00000000..e15bee91 --- /dev/null +++ b/node_modules/signals/dist/docs/symbols/signals.Signal.html @@ -0,0 +1,594 @@ + + + + + + + JsDoc Reference - signals.Signal + + + + + + + + + + + + + +
    +
    + +
    + +

    Index

    + +

    Classes

    + + +
    + +
    + + +

    + Class +

    + + + + + + + +

    Fields

    + + + + + + + +

    Methods

    + + + + + + + + +
    + +
    + +

    + Class signals.Signal +

    + + +

    + + + + + + +
    Defined in: js-signals.js. + +

    + + + +
    +
    + Class Detail +
    + +
    + signals.Signal() +
    + +
    +

    Custom event broadcaster +
    - inspired by Robert Penner's AS3 Signals.

    +
    Author: Miller Medeiros. +
    + + + + + + + + + + + + +
    + + + + +
    +
    + Field Detail +
    + +
    + +
    +
    +
    + + {boolean} + active + +
    +
    +

    If Signal is active and should broadcast events.

    + +

    IMPORTANT: Setting this property during a dispatch will only affect the next dispatch, if you want to stop the propagation of a signal use `halt()` instead.

    + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + Method Detail +
    + +
    + +
    +
    +
    + {SignalBinding} + add(listener, scope, priority) + +
    +
    +

    Add a listener to the signal.

    + + +
    + + + + +
    +
    Parameters:
    + +
    + {Function} listener + +
    +
    Signal handler function.
    + +
    + {Object} scope + Optional +
    +
    Context on which listener will be executed (object that should represent the `this` variable inside listener function).
    + +
    + {Number} priority + Optional +
    +
    The priority level of the event listener. Listeners with higher priority will be executed before listeners with lower priority. Listeners with same priority level will be executed at the same order as they were added. (default = 0)
    + +
    + + + + + +
    +
    Returns:
    + +
    {SignalBinding} An Object representing the binding between the Signal and listener.
    + +
    + + + + +
    + +
    + +
    +
    +
    + {SignalBinding} + addOnce(listener, scope, priority) + +
    +
    +

    Add listener to the signal that should be removed after first execution (will be executed only once).

    + + +
    + + + + +
    +
    Parameters:
    + +
    + {Function} listener + +
    +
    Signal handler function.
    + +
    + {Object} scope + Optional +
    +
    Context on which listener will be executed (object that should represent the `this` variable inside listener function).
    + +
    + {Number} priority + Optional +
    +
    The priority level of the event listener. Listeners with higher priority will be executed before listeners with lower priority. Listeners with same priority level will be executed at the same order as they were added. (default = 0)
    + +
    + + + + + +
    +
    Returns:
    + +
    {SignalBinding} An Object representing the binding between the Signal and listener.
    + +
    + + + + +
    + +
    + +
    +
    +
    + + dispatch(params) + +
    +
    +

    Dispatch/Broadcast Signal to all listeners added to the queue.

    + + +
    + + + + +
    +
    Parameters:
    + +
    + {...*} params + Optional +
    +
    Parameters that should be passed to each handler.
    + +
    + + + + + + + + +
    + +
    + +
    +
    +
    + + dispose() + +
    +
    +

    Remove all bindings from signal and destroy any reference to external objects (destroy Signal object).

    + +

    IMPORTANT: calling any method on the signal instance after calling dispose will throw errors.

    + + +
    + + + + + + + + + + + +
    + +
    + +
    +
    +
    + {number} + getNumListeners() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {number} Number of listeners attached to the Signal.
    + +
    + + + + +
    + +
    + +
    +
    +
    + + halt() + +
    +
    +

    Stop propagation of the event, blocking the dispatch to next listeners on the queue.

    + +

    IMPORTANT: should be called only during signal dispatch, calling it before/after dispatch won't affect signal broadcast.

    + + +
    + + + + + + + + + + +
    +
    See:
    + +
    signals.Signal.prototype.disable
    + +
    + + +
    + +
    + +
    +
    +
    + {Function} + remove(listener) + +
    +
    +

    Remove a single listener from the dispatch queue.

    + + +
    + + + + +
    +
    Parameters:
    + +
    + {Function} listener + +
    +
    Handler function that should be removed.
    + +
    + + + + + +
    +
    Returns:
    + +
    {Function} Listener handler function.
    + +
    + + + + +
    + +
    + +
    +
    +
    + + removeAll() + +
    +
    +

    Remove all listeners from the Signal.

    + + +
    + + + + + + + + + + + +
    + +
    + +
    +
    +
    + {string} + toString() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {string} String representation of the object.
    + +
    + + + + +
    + +
    + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Tue May 03 2011 01:07:20 GMT-0300 (BRT) + | template based on Steffen Siering jsdoc-simple. +
    + + diff --git a/node_modules/signals/dist/docs/symbols/signals.SignalBinding.html b/node_modules/signals/dist/docs/symbols/signals.SignalBinding.html new file mode 100644 index 00000000..b578d9d6 --- /dev/null +++ b/node_modules/signals/dist/docs/symbols/signals.SignalBinding.html @@ -0,0 +1,500 @@ + + + + + + + JsDoc Reference - signals.SignalBinding + + + + + + + + + + + + + +
    +
    + +
    + +

    Index

    + +

    Classes

    + + +
    + +
    + + +

    + Class +

    + + + + + + + +

    Fields

    + + + + + + + +

    Methods

    + + + + + + + + +
    + +
    + +

    + Class signals.SignalBinding +

    + + +

    + + + + + + +
    Defined in: js-signals.js. + +

    + + + +
    +
    + Class Detail +
    + +
    + signals.SignalBinding(signal, listener, isOnce, listenerContext, priority) +
    + +
    +

    Object that represents a binding between a Signal and a listener function. +
    - This is an internal constructor and shouldn't be called by regular users. +
    - inspired by Joa Ebert AS3 SignalBinding and Robert Penner's Slot classes.

    +
    Author: Miller Medeiros. +
    + + + + + +
    +
    Parameters:
    + +
    + {signals.Signal} signal + +
    +
    Reference to Signal object that listener is currently bound to.
    + +
    + {Function} listener + +
    +
    Handler function bound to the signal.
    + +
    + {boolean} isOnce + +
    +
    If binding should be executed just once.
    + +
    + {Object} listenerContext + Optional +
    +
    Context on which listener will be executed (object that should represent the `this` variable inside listener function).
    + +
    + {Number} priority + Optional +
    +
    The priority level of the event listener. (default = 0).
    + +
    + + + + + + + + +
    + + + + +
    +
    + Field Detail +
    + +
    + +
    +
    +
    + + {boolean} + active + +
    +
    +

    If binding is active and should be executed.

    + + +
    + + + + + + + +
    + +
    + +
    +
    +
    + + {Object|undefined|null} + context + +
    +
    +

    Context on which listener will be executed (object that should represent the this variable inside listener function).

    + + +
    + + + + + + + +
    + +
    + + + + +
    +
    + Method Detail +
    + +
    + +
    +
    +
    + {Function} + detach() + +
    +
    +

    Detach binding from signal. +- alias to: mySignal.remove(myBinding.getListener());

    + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Function} Handler function bound to the signal.
    + +
    + + + + +
    + +
    + +
    +
    +
    + + dispose() + +
    +
    +

    Remove binding from signal and destroy any reference to external Objects (destroy SignalBinding object).

    + +

    IMPORTANT: calling methods on the binding instance after calling dispose will throw errors.

    + + +
    + + + + + + + + + + + +
    + +
    + +
    +
    +
    + {*} + execute(paramsArr) + +
    +
    +

    Call listener passing arbitrary parameters.

    + +

    If binding was added using `Signal.addOnce()` it will be automatically removed from signal dispatch queue, this method is used internally for the signal dispatch.

    + + +
    + + + + +
    +
    Parameters:
    + +
    + {Array} paramsArr + Optional +
    +
    Array of parameters that should be passed to the listener
    + +
    + + + + + +
    +
    Returns:
    + +
    {*} Value returned by the listener.
    + +
    + + + + +
    + +
    + +
    +
    +
    + {Function} + getListener() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Function} Handler function bound to the signal.
    + +
    + + + + +
    + +
    + +
    +
    +
    + {boolean} + isOnce() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {boolean} If SignalBinding will only be executed once.
    + +
    + + + + +
    + +
    + +
    +
    +
    + {string} + toString() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {string} String representation of the object.
    + +
    + + + + +
    + +
    + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Tue May 03 2011 01:07:20 GMT-0300 (BRT) + | template based on Steffen Siering jsdoc-simple. +
    + + diff --git a/node_modules/signals/dist/docs/symbols/signals.html b/node_modules/signals/dist/docs/symbols/signals.html new file mode 100644 index 00000000..263c648c --- /dev/null +++ b/node_modules/signals/dist/docs/symbols/signals.html @@ -0,0 +1,186 @@ + + + + + + + JsDoc Reference - signals + + + + + + + + + + + + + +
    +
    + +
    + +

    Index

    + +

    Classes

    + + +
    + +
    + + +

    + Namespace +

    + + + + + + + +

    Variables

    + + + + + + + + + + + + + +
    + +
    + +

    + Namespace signals +

    + + +

    + + + + Signals Namespace - Custom event/messaging system based on AS3 Signals + + +
    Defined in: js-signals.js. + +

    + + + +
    +
    + Namespace Detail +
    + +
    + signals +
    + +
    + + +
    + + + + + + + + + + + + +
    + + + + +
    +
    + Field Detail +
    + +
    + +
    +
    <static> +
    + + {String} + signals.VERSION + +
    +
    +

    Signals Version Number

    + + +
    + + + + + + + +
    + +
    + + + + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Tue May 03 2011 01:07:19 GMT-0300 (BRT) + | template based on Steffen Siering jsdoc-simple. +
    + + diff --git a/node_modules/signals/dist/docs/symbols/src/_Users_millermedeiros_Projects__open_source_js-signals_dist_js-signals.js.html b/node_modules/signals/dist/docs/symbols/src/_Users_millermedeiros_Projects__open_source_js-signals_dist_js-signals.js.html new file mode 100644 index 00000000..f7c14d51 --- /dev/null +++ b/node_modules/signals/dist/docs/symbols/src/_Users_millermedeiros_Projects__open_source_js-signals_dist_js-signals.js.html @@ -0,0 +1,363 @@ +
      1 /*jslint onevar:true, undef:true, newcap:true, regexp:true, bitwise:true, maxerr:50, indent:4, white:false, nomen:false, plusplus:false */
    +  2 /*global window:false, global:false*/
    +  3 
    +  4 /*!!
    +  5  * JS Signals <http://millermedeiros.github.com/js-signals/>
    +  6  * Released under the MIT license <http://www.opensource.org/licenses/mit-license.php>
    +  7  * @author Miller Medeiros <http://millermedeiros.com/>
    +  8  * @version 0.6.1
    +  9  * @build 178 (05/03/2011 01:07 AM)
    + 10  */
    + 11 (function(global){
    + 12 	
    + 13 	/**
    + 14 	 * @namespace Signals Namespace - Custom event/messaging system based on AS3 Signals
    + 15 	 * @name signals
    + 16 	 */
    + 17 	var signals = /** @lends signals */{
    + 18 		/**
    + 19 		 * Signals Version Number
    + 20 		 * @type String
    + 21 		 * @const
    + 22 		 */
    + 23 		VERSION : '0.6.1'
    + 24 	};
    + 25 
    + 26 	// SignalBinding -------------------------------------------------
    + 27 	//================================================================
    + 28 	
    + 29 	/**
    + 30 	 * Object that represents a binding between a Signal and a listener function.
    + 31 	 * <br />- <strong>This is an internal constructor and shouldn't be called by regular users.</strong>
    + 32 	 * <br />- inspired by Joa Ebert AS3 SignalBinding and Robert Penner's Slot classes.
    + 33 	 * @author Miller Medeiros
    + 34 	 * @constructor
    + 35 	 * @internal
    + 36 	 * @name signals.SignalBinding
    + 37 	 * @param {signals.Signal} signal	Reference to Signal object that listener is currently bound to.
    + 38 	 * @param {Function} listener	Handler function bound to the signal.
    + 39 	 * @param {boolean} isOnce	If binding should be executed just once.
    + 40 	 * @param {Object} [listenerContext]	Context on which listener will be executed (object that should represent the `this` variable inside listener function).
    + 41 	 * @param {Number} [priority]	The priority level of the event listener. (default = 0).
    + 42 	 */
    + 43 	 function SignalBinding(signal, listener, isOnce, listenerContext, priority){
    + 44 		
    + 45 		/**
    + 46 		 * Handler function bound to the signal.
    + 47 		 * @type Function
    + 48 		 * @private
    + 49 		 */
    + 50 		this._listener = listener;
    + 51 		
    + 52 		/**
    + 53 		 * If binding should be executed just once.
    + 54 		 * @type boolean
    + 55 		 * @private
    + 56 		 */
    + 57 		this._isOnce = isOnce;
    + 58 		
    + 59 		/**
    + 60 		 * Context on which listener will be executed (object that should represent the `this` variable inside listener function).
    + 61 		 * @memberOf signals.SignalBinding.prototype
    + 62 		 * @name context
    + 63 		 * @type Object|undefined|null
    + 64 		 */
    + 65 		this.context = listenerContext;
    + 66 		
    + 67 		/**
    + 68 		 * Reference to Signal object that listener is currently bound to.
    + 69 		 * @type signals.Signal
    + 70 		 * @private
    + 71 		 */
    + 72 		this._signal = signal;
    + 73 		
    + 74 		/**
    + 75 		 * Listener priority
    + 76 		 * @type Number
    + 77 		 * @private
    + 78 		 */
    + 79 		this._priority = priority || 0;
    + 80 	}
    + 81 	
    + 82 	SignalBinding.prototype = /** @lends signals.SignalBinding.prototype */ {
    + 83 		
    + 84 		/**
    + 85 		 * If binding is active and should be executed.
    + 86 		 * @type boolean
    + 87 		 */
    + 88 		active : true,
    + 89 		
    + 90 		/**
    + 91 		 * Call listener passing arbitrary parameters.
    + 92 		 * <p>If binding was added using `Signal.addOnce()` it will be automatically removed from signal dispatch queue, this method is used internally for the signal dispatch.</p> 
    + 93 		 * @param {Array} [paramsArr]	Array of parameters that should be passed to the listener
    + 94 		 * @return {*} Value returned by the listener.
    + 95 		 */
    + 96 		execute : function(paramsArr){
    + 97 			var r;
    + 98 			if(this.active){
    + 99 				r = this._listener.apply(this.context, paramsArr);
    +100 				if(this._isOnce){
    +101 					this.detach();
    +102 				}
    +103 			}
    +104 			return r;
    +105 		},
    +106 		
    +107 		/**
    +108 		 * Detach binding from signal.
    +109 		 * - alias to: mySignal.remove(myBinding.getListener());
    +110 		 * @return {Function} Handler function bound to the signal.
    +111 		 */
    +112 		detach : function(){
    +113 			return this._signal.remove(this._listener);
    +114 		},
    +115 		
    +116 		/**
    +117 		 * @return {Function} Handler function bound to the signal.
    +118 		 */
    +119 		getListener : function(){
    +120 			return this._listener;
    +121 		},
    +122 		
    +123 		/**
    +124 		 * Remove binding from signal and destroy any reference to external Objects (destroy SignalBinding object).
    +125 		 * <p><strong>IMPORTANT:</strong> calling methods on the binding instance after calling dispose will throw errors.</p>
    +126 		 */
    +127 		dispose : function(){
    +128 			this.detach();
    +129 			this._destroy();
    +130 		},
    +131 		
    +132 		/**
    +133 		 * Delete all instance properties
    +134 		 * @private
    +135 		 */
    +136 		_destroy : function(){
    +137 			delete this._signal;
    +138 			delete this._isOnce;
    +139 			delete this._listener;
    +140 			delete this.context;
    +141 		},
    +142 		
    +143 		/**
    +144 		 * @return {boolean} If SignalBinding will only be executed once.
    +145 		 */
    +146 		isOnce : function(){
    +147 			return this._isOnce;
    +148 		},
    +149 		
    +150 		/**
    +151 		 * @return {string} String representation of the object.
    +152 		 */
    +153 		toString : function(){
    +154 			return '[SignalBinding isOnce: '+ this._isOnce +', active: '+ this.active +']';
    +155 		}
    +156 		
    +157 	};
    +158 
    +159 /*global signals:true, SignalBinding:true*/
    +160 	
    +161 	// Signal --------------------------------------------------------
    +162 	//================================================================
    +163 	
    +164 	/**
    +165 	 * Custom event broadcaster
    +166 	 * <br />- inspired by Robert Penner's AS3 Signals.
    +167 	 * @author Miller Medeiros
    +168 	 * @constructor
    +169 	 */
    +170 	signals.Signal = function(){
    +171 		/**
    +172 		 * @type Array.<SignalBinding>
    +173 		 * @private
    +174 		 */
    +175 		this._bindings = [];
    +176 	};
    +177 	
    +178 	signals.Signal.prototype = {
    +179 		
    +180 		/**
    +181 		 * @type boolean
    +182 		 * @private
    +183 		 */
    +184 		_shouldPropagate : true,
    +185 		
    +186 		/**
    +187 		 * If Signal is active and should broadcast events.
    +188 		 * <p><strong>IMPORTANT:</strong> Setting this property during a dispatch will only affect the next dispatch, if you want to stop the propagation of a signal use `halt()` instead.</p>
    +189 		 * @type boolean
    +190 		 */
    +191 		active : true,
    +192 		
    +193 		/**
    +194 		 * @param {Function} listener
    +195 		 * @param {boolean} isOnce
    +196 		 * @param {Object} [scope]
    +197 		 * @param {Number} [priority]
    +198 		 * @return {SignalBinding}
    +199 		 * @private
    +200 		 */
    +201 		_registerListener : function(listener, isOnce, scope, priority){
    +202 			
    +203 			if(typeof listener !== 'function'){
    +204 				throw new Error('listener is a required param of add() and addOnce() and should be a Function.');
    +205 			}
    +206 			
    +207 			var prevIndex = this._indexOfListener(listener),
    +208 				binding;
    +209 			
    +210 			if(prevIndex !== -1){ //avoid creating a new Binding for same listener if already added to list
    +211 				binding = this._bindings[prevIndex];
    +212 				if(binding.isOnce() !== isOnce){
    +213 					throw new Error('You cannot add'+ (isOnce? '' : 'Once') +'() then add'+ (!isOnce? '' : 'Once') +'() the same listener without removing the relationship first.');
    +214 				}
    +215 			} else {
    +216 				binding = new SignalBinding(this, listener, isOnce, scope, priority);
    +217 				this._addBinding(binding);
    +218 			}
    +219 			
    +220 			return binding;
    +221 		},
    +222 		
    +223 		/**
    +224 		 * @param {Function} binding
    +225 		 * @private
    +226 		 */
    +227 		_addBinding : function(binding){
    +228 			//simplified insertion sort
    +229 			var n = this._bindings.length;
    +230 			do { --n; } while (this._bindings[n] && binding._priority <= this._bindings[n]._priority);
    +231 			this._bindings.splice(n+1, 0, binding);
    +232 		},
    +233 		
    +234 		/**
    +235 		 * @param {Function} listener
    +236 		 * @return {number}
    +237 		 * @private
    +238 		 */
    +239 		_indexOfListener : function(listener){
    +240 			var n = this._bindings.length;
    +241 			while(n--){
    +242 				if(this._bindings[n]._listener === listener){
    +243 					return n;
    +244 				}
    +245 			}
    +246 			return -1;
    +247 		},
    +248 		
    +249 		/**
    +250 		 * Add a listener to the signal.
    +251 		 * @param {Function} listener	Signal handler function.
    +252 		 * @param {Object} [scope]	Context on which listener will be executed (object that should represent the `this` variable inside listener function).
    +253 		 * @param {Number} [priority]	The priority level of the event listener. Listeners with higher priority will be executed before listeners with lower priority. Listeners with same priority level will be executed at the same order as they were added. (default = 0)
    +254 		 * @return {SignalBinding} An Object representing the binding between the Signal and listener.
    +255 		 */
    +256 		add : function(listener, scope, priority){
    +257 			return this._registerListener(listener, false, scope, priority);
    +258 		},
    +259 		
    +260 		/**
    +261 		 * Add listener to the signal that should be removed after first execution (will be executed only once).
    +262 		 * @param {Function} listener	Signal handler function.
    +263 		 * @param {Object} [scope]	Context on which listener will be executed (object that should represent the `this` variable inside listener function).
    +264 		 * @param {Number} [priority]	The priority level of the event listener. Listeners with higher priority will be executed before listeners with lower priority. Listeners with same priority level will be executed at the same order as they were added. (default = 0)
    +265 		 * @return {SignalBinding} An Object representing the binding between the Signal and listener.
    +266 		 */
    +267 		addOnce : function(listener, scope, priority){
    +268 			return this._registerListener(listener, true, scope, priority);
    +269 		},
    +270 		
    +271 		/**
    +272 		 * Remove a single listener from the dispatch queue.
    +273 		 * @param {Function} listener	Handler function that should be removed.
    +274 		 * @return {Function} Listener handler function.
    +275 		 */
    +276 		remove : function(listener){
    +277 			if(typeof listener !== 'function'){
    +278 				throw new Error('listener is a required param of remove() and should be a Function.');
    +279 			}
    +280 			
    +281 			var i = this._indexOfListener(listener);
    +282 			if(i !== -1){
    +283 				this._bindings[i]._destroy(); //no reason to a SignalBinding exist if it isn't attached to a signal
    +284 				this._bindings.splice(i, 1);
    +285 			}
    +286 			return listener;
    +287 		},
    +288 		
    +289 		/**
    +290 		 * Remove all listeners from the Signal.
    +291 		 */
    +292 		removeAll : function(){
    +293 			var n = this._bindings.length;
    +294 			while(n--){
    +295 				this._bindings[n]._destroy();
    +296 			}
    +297 			this._bindings.length = 0;
    +298 		},
    +299 		
    +300 		/**
    +301 		 * @return {number} Number of listeners attached to the Signal.
    +302 		 */
    +303 		getNumListeners : function(){
    +304 			return this._bindings.length;
    +305 		},
    +306 		
    +307 		/**
    +308 		 * Stop propagation of the event, blocking the dispatch to next listeners on the queue.
    +309 		 * <p><strong>IMPORTANT:</strong> should be called only during signal dispatch, calling it before/after dispatch won't affect signal broadcast.</p>
    +310 		 * @see signals.Signal.prototype.disable 
    +311 		 */
    +312 		halt : function(){
    +313 			this._shouldPropagate = false;
    +314 		},
    +315 		
    +316 		/**
    +317 		 * Dispatch/Broadcast Signal to all listeners added to the queue. 
    +318 		 * @param {...*} [params]	Parameters that should be passed to each handler.
    +319 		 */
    +320 		dispatch : function(params){
    +321 			if(! this.active){
    +322 				return;
    +323 			}
    +324 			
    +325 			var paramsArr = Array.prototype.slice.call(arguments),
    +326 				bindings = this._bindings.slice(), //clone array in case add/remove items during dispatch
    +327 				n = this._bindings.length;
    +328 			
    +329 			this._shouldPropagate = true; //in case `halt` was called before dispatch or during the previous dispatch.
    +330 			
    +331 			//execute all callbacks until end of the list or until a callback returns `false` or stops propagation
    +332 			//reverse loop since listeners with higher priority will be added at the end of the list
    +333 			do { n--; } while (bindings[n] && this._shouldPropagate && bindings[n].execute(paramsArr) !== false);
    +334 		},
    +335 		
    +336 		/**
    +337 		 * Remove all bindings from signal and destroy any reference to external objects (destroy Signal object).
    +338 		 * <p><strong>IMPORTANT:</strong> calling any method on the signal instance after calling dispose will throw errors.</p>
    +339 		 */
    +340 		dispose : function(){
    +341 			this.removeAll();
    +342 			delete this._bindings;
    +343 		},
    +344 		
    +345 		/**
    +346 		 * @return {string} String representation of the object.
    +347 		 */
    +348 		toString : function(){
    +349 			return '[Signal active: '+ this.active +' numListeners: '+ this.getNumListeners() +']';
    +350 		}
    +351 		
    +352 	};
    +353 
    +354 	global.signals = signals;
    +355 	
    +356 }(window || global || this));
    \ No newline at end of file diff --git a/node_modules/signals/dist/js-signals.cjs.js b/node_modules/signals/dist/js-signals.cjs.js new file mode 100644 index 00000000..3f61d391 --- /dev/null +++ b/node_modules/signals/dist/js-signals.cjs.js @@ -0,0 +1,354 @@ +/*jslint onevar:true, undef:true, newcap:true, regexp:true, bitwise:true, maxerr:50, indent:4, white:false, nomen:false, plusplus:false */ +/*global module:false*/ + +/*!! + * JS Signals + * Released under the MIT license + * @author Miller Medeiros + * @version 0.6.1 + * @build 179 (05/03/2011 01:20 AM) + */ + + /** + * @namespace Signals Namespace - Custom event/messaging system based on AS3 Signals + * @name signals + */ + var signals = /** @lends signals */{ + /** + * Signals Version Number + * @type String + * @const + */ + VERSION : '0.6.1' + }; + + // SignalBinding ------------------------------------------------- + //================================================================ + + /** + * Object that represents a binding between a Signal and a listener function. + *
    - This is an internal constructor and shouldn't be called by regular users. + *
    - inspired by Joa Ebert AS3 SignalBinding and Robert Penner's Slot classes. + * @author Miller Medeiros + * @constructor + * @internal + * @name signals.SignalBinding + * @param {signals.Signal} signal Reference to Signal object that listener is currently bound to. + * @param {Function} listener Handler function bound to the signal. + * @param {boolean} isOnce If binding should be executed just once. + * @param {Object} [listenerContext] Context on which listener will be executed (object that should represent the `this` variable inside listener function). + * @param {Number} [priority] The priority level of the event listener. (default = 0). + */ + function SignalBinding(signal, listener, isOnce, listenerContext, priority){ + + /** + * Handler function bound to the signal. + * @type Function + * @private + */ + this._listener = listener; + + /** + * If binding should be executed just once. + * @type boolean + * @private + */ + this._isOnce = isOnce; + + /** + * Context on which listener will be executed (object that should represent the `this` variable inside listener function). + * @memberOf signals.SignalBinding.prototype + * @name context + * @type Object|undefined|null + */ + this.context = listenerContext; + + /** + * Reference to Signal object that listener is currently bound to. + * @type signals.Signal + * @private + */ + this._signal = signal; + + /** + * Listener priority + * @type Number + * @private + */ + this._priority = priority || 0; + } + + SignalBinding.prototype = /** @lends signals.SignalBinding.prototype */ { + + /** + * If binding is active and should be executed. + * @type boolean + */ + active : true, + + /** + * Call listener passing arbitrary parameters. + *

    If binding was added using `Signal.addOnce()` it will be automatically removed from signal dispatch queue, this method is used internally for the signal dispatch.

    + * @param {Array} [paramsArr] Array of parameters that should be passed to the listener + * @return {*} Value returned by the listener. + */ + execute : function(paramsArr){ + var r; + if(this.active){ + r = this._listener.apply(this.context, paramsArr); + if(this._isOnce){ + this.detach(); + } + } + return r; + }, + + /** + * Detach binding from signal. + * - alias to: mySignal.remove(myBinding.getListener()); + * @return {Function} Handler function bound to the signal. + */ + detach : function(){ + return this._signal.remove(this._listener); + }, + + /** + * @return {Function} Handler function bound to the signal. + */ + getListener : function(){ + return this._listener; + }, + + /** + * Remove binding from signal and destroy any reference to external Objects (destroy SignalBinding object). + *

    IMPORTANT: calling methods on the binding instance after calling dispose will throw errors.

    + */ + dispose : function(){ + this.detach(); + this._destroy(); + }, + + /** + * Delete all instance properties + * @private + */ + _destroy : function(){ + delete this._signal; + delete this._isOnce; + delete this._listener; + delete this.context; + }, + + /** + * @return {boolean} If SignalBinding will only be executed once. + */ + isOnce : function(){ + return this._isOnce; + }, + + /** + * @return {string} String representation of the object. + */ + toString : function(){ + return '[SignalBinding isOnce: '+ this._isOnce +', active: '+ this.active +']'; + } + + }; + +/*global signals:true, SignalBinding:true*/ + + // Signal -------------------------------------------------------- + //================================================================ + + /** + * Custom event broadcaster + *
    - inspired by Robert Penner's AS3 Signals. + * @author Miller Medeiros + * @constructor + */ + signals.Signal = function(){ + /** + * @type Array. + * @private + */ + this._bindings = []; + }; + + signals.Signal.prototype = { + + /** + * @type boolean + * @private + */ + _shouldPropagate : true, + + /** + * If Signal is active and should broadcast events. + *

    IMPORTANT: Setting this property during a dispatch will only affect the next dispatch, if you want to stop the propagation of a signal use `halt()` instead.

    + * @type boolean + */ + active : true, + + /** + * @param {Function} listener + * @param {boolean} isOnce + * @param {Object} [scope] + * @param {Number} [priority] + * @return {SignalBinding} + * @private + */ + _registerListener : function(listener, isOnce, scope, priority){ + + if(typeof listener !== 'function'){ + throw new Error('listener is a required param of add() and addOnce() and should be a Function.'); + } + + var prevIndex = this._indexOfListener(listener), + binding; + + if(prevIndex !== -1){ //avoid creating a new Binding for same listener if already added to list + binding = this._bindings[prevIndex]; + if(binding.isOnce() !== isOnce){ + throw new Error('You cannot add'+ (isOnce? '' : 'Once') +'() then add'+ (!isOnce? '' : 'Once') +'() the same listener without removing the relationship first.'); + } + } else { + binding = new SignalBinding(this, listener, isOnce, scope, priority); + this._addBinding(binding); + } + + return binding; + }, + + /** + * @param {Function} binding + * @private + */ + _addBinding : function(binding){ + //simplified insertion sort + var n = this._bindings.length; + do { --n; } while (this._bindings[n] && binding._priority <= this._bindings[n]._priority); + this._bindings.splice(n+1, 0, binding); + }, + + /** + * @param {Function} listener + * @return {number} + * @private + */ + _indexOfListener : function(listener){ + var n = this._bindings.length; + while(n--){ + if(this._bindings[n]._listener === listener){ + return n; + } + } + return -1; + }, + + /** + * Add a listener to the signal. + * @param {Function} listener Signal handler function. + * @param {Object} [scope] Context on which listener will be executed (object that should represent the `this` variable inside listener function). + * @param {Number} [priority] The priority level of the event listener. Listeners with higher priority will be executed before listeners with lower priority. Listeners with same priority level will be executed at the same order as they were added. (default = 0) + * @return {SignalBinding} An Object representing the binding between the Signal and listener. + */ + add : function(listener, scope, priority){ + return this._registerListener(listener, false, scope, priority); + }, + + /** + * Add listener to the signal that should be removed after first execution (will be executed only once). + * @param {Function} listener Signal handler function. + * @param {Object} [scope] Context on which listener will be executed (object that should represent the `this` variable inside listener function). + * @param {Number} [priority] The priority level of the event listener. Listeners with higher priority will be executed before listeners with lower priority. Listeners with same priority level will be executed at the same order as they were added. (default = 0) + * @return {SignalBinding} An Object representing the binding between the Signal and listener. + */ + addOnce : function(listener, scope, priority){ + return this._registerListener(listener, true, scope, priority); + }, + + /** + * Remove a single listener from the dispatch queue. + * @param {Function} listener Handler function that should be removed. + * @return {Function} Listener handler function. + */ + remove : function(listener){ + if(typeof listener !== 'function'){ + throw new Error('listener is a required param of remove() and should be a Function.'); + } + + var i = this._indexOfListener(listener); + if(i !== -1){ + this._bindings[i]._destroy(); //no reason to a SignalBinding exist if it isn't attached to a signal + this._bindings.splice(i, 1); + } + return listener; + }, + + /** + * Remove all listeners from the Signal. + */ + removeAll : function(){ + var n = this._bindings.length; + while(n--){ + this._bindings[n]._destroy(); + } + this._bindings.length = 0; + }, + + /** + * @return {number} Number of listeners attached to the Signal. + */ + getNumListeners : function(){ + return this._bindings.length; + }, + + /** + * Stop propagation of the event, blocking the dispatch to next listeners on the queue. + *

    IMPORTANT: should be called only during signal dispatch, calling it before/after dispatch won't affect signal broadcast.

    + * @see signals.Signal.prototype.disable + */ + halt : function(){ + this._shouldPropagate = false; + }, + + /** + * Dispatch/Broadcast Signal to all listeners added to the queue. + * @param {...*} [params] Parameters that should be passed to each handler. + */ + dispatch : function(params){ + if(! this.active){ + return; + } + + var paramsArr = Array.prototype.slice.call(arguments), + bindings = this._bindings.slice(), //clone array in case add/remove items during dispatch + n = this._bindings.length; + + this._shouldPropagate = true; //in case `halt` was called before dispatch or during the previous dispatch. + + //execute all callbacks until end of the list or until a callback returns `false` or stops propagation + //reverse loop since listeners with higher priority will be added at the end of the list + do { n--; } while (bindings[n] && this._shouldPropagate && bindings[n].execute(paramsArr) !== false); + }, + + /** + * Remove all bindings from signal and destroy any reference to external objects (destroy Signal object). + *

    IMPORTANT: calling any method on the signal instance after calling dispose will throw errors.

    + */ + dispose : function(){ + this.removeAll(); + delete this._bindings; + }, + + /** + * @return {string} String representation of the object. + */ + toString : function(){ + return '[Signal active: '+ this.active +' numListeners: '+ this.getNumListeners() +']'; + } + + }; + +module.exports = signals; + diff --git a/node_modules/signals/package.json b/node_modules/signals/package.json new file mode 100644 index 00000000..287fd47c --- /dev/null +++ b/node_modules/signals/package.json @@ -0,0 +1,25 @@ +{ + "name" : "signals", + "description" : "Custom Event/Messaging System", + "keywords" : ["js-signals", "signals", "pub/sub", "event", "publish", "subscribe", "observer"], + "homepage" : "http://millermedeiros.github.com/js-signals/", + "version" : "0.6.1", + "author" : "Miller Medeiros", + "repository" : { + "type" : "git", + "url" : "https://github.com/millermedeiros/js-signals.git" + }, + "main" : "dist/js-signals.cjs.js", + "bugs" : { + "web" : "https://github.com/millermedeiros/js-signals/issues" + }, + "directories" : { + "doc" : "./dist/docs" + }, + "licenses" : [ + { + "type" : "MIT", + "url" : "http://www.opensource.org/licenses/mit-license.php" + } + ] +} \ No newline at end of file diff --git a/node_modules/underscore.string/.gitignore b/node_modules/underscore.string/.gitignore new file mode 100644 index 00000000..496ee2ca --- /dev/null +++ b/node_modules/underscore.string/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/node_modules/underscore.string/.hgignore b/node_modules/underscore.string/.hgignore new file mode 100644 index 00000000..9b4e43b9 --- /dev/null +++ b/node_modules/underscore.string/.hgignore @@ -0,0 +1,5 @@ +glob:.git +glob:.project +glob:index.html +glob:*.swp +glob:.DS_Store \ No newline at end of file diff --git a/node_modules/underscore.string/README.markdown b/node_modules/underscore.string/README.markdown new file mode 100644 index 00000000..44fe372b --- /dev/null +++ b/node_modules/underscore.string/README.markdown @@ -0,0 +1,339 @@ +# Underscore.string # + +Idea: Esa-Matti Suuronen (esa-matti aet suuronen dot org) + +Authors: Esa-Matti Suuronen, Edward Tsech + +Javascript lacks complete string manipulation operations. +This an attempt to fill that cap. List of buildin methods can be found +for example from [Dive Into JavaScript][d]. + +[d]: http://www.diveintojavascript.com/core-javascript-reference/the-string-object + + +As name states this an extension for [Underscore.js][u], but it can be used +independently from **_s**-global variable. But with Underscore.js you can +use Object-Oriented style and chaining: + +[u]: http://documentcloud.github.com/underscore/ + + _(" epeli ").chain().trim().capitalize().value() + => "Epeli" + +## Node.js installation ## + +**npm package** + + npm install underscore.string + +**Standalone usage**: + + var _s = require('undescore.string'); + +**Integrate with Underscore.js**: + + var _ = require('underscore'); + _.mixin(require('underscore.string')); + +## String Functions ## + +**capitalize** _.capitalize(string) + +Converts first letter of the string to uppercase. + + _.capitalize("epeli") + => "Epeli" + +**chop** _.chop(string, step) + + _.chop('whitespace', 3) + => ['whi','tes','pac','e'] + +**clean** _.clean(str) + +Compress some whitespaces to one. + + _.clean(" foo bar ") + => 'foo bar' + +**chars** _.chars(str) + + _.chars('Hello') + => ['H','e','l','l','o'] + +**includes** _.includes(string, substring) + +Tests if string contains a substring. + + _.includes("foobar", "ob") + => true + +**count** _.count(string, substring) + + _('Hello world').count('l') + => 3 + +**escapeHTML** _.escapeHTML(string) + +Converts HTML special characters to their entity equivalents. + + _('
    Blah blah blah
    ').escapeHTML(); + => '<div>Blah blah blah</div>' + +**unescapeHTML** _.unescapeHTML(string) + +Converts entity characters to HTML equivalents. + + _('<div>Blah blah blah</div>').unescapeHTML(); + => '
    Blah blah blah
    ' + +**insert** _.insert(string, index, substing) + + _('Hello ').insert(6, 'world') + => 'Hello world' + +**join** _.join(separator, *strings) + +Joins strings together with given separator + + _.join(" ", "foo", "bar") + => "foo bar" + +**lines** _.lines(str) + + _.lines("Hello\nWorld") + => ["Hello", "World"] + +**reverse** + +This functions has been removed, because this function override underscore.js 'reverse'. +But now you can do that: + + _("foobar").chars().reverse().join('') + +**splice** _.splice(string, index, howmany, substring) + +Like a array splice. + + _('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli') + => 'https://edtsech@bitbucket.org/epeli/underscore.strings' + +**startsWith** _.startsWith(string, starts) + +This method checks whether string starts with starts. + + _("image.gif").startsWith("image") + => true + +**endsWith** _.endsWith(string, ends) + +This method checks whether string ends with ends. + + _("image.gif").endsWith("gif") + => true + +**succ** _.succ(str) + +Returns the successor to str. + + _('a').succ() + => 'b' + + _('A').succ() + => 'B' + +**supplant** + +Supplant function was removed, use Underscore.js [template function][p]. + +[p]: http://documentcloud.github.com/underscore/#template + +**strip** alias for *trim* + +**lstrip** alias for *ltrim* + +**rstrip** alias for *rtrim* + +**titleize** _.titleize(string) + + _('my name is epeli').titleize() + => 'My Name Is Epeli' + +**camelize** _.camelize(string) + +Converts underscored or dasherized string to a camelized one + + _('-moz-transform').camelize() + => 'MozTransform' + +**underscored** _.underscored(string) + +Converts a camelized or dasherized string into an underscored one + + _(MozTransform).underscored() + => 'moz_transform' + +**dasherize** _.dasherize(string) + +Converts a underscored or camelized string into an dasherized one + + _('MozTransform').dasherize() + => '-moz-transform' + +**trim** _.trim(string, [characters]) + +trims defined characters from begining and ending of the string. +Defaults to whitespace characters. + + _.trim(" foobar ") + => "foobar" + + _.trim("_-foobar-_", "_-") + => "foobar" + + +**ltrim** _.ltrim(string, [characters]) + +Left trim. Similar to trim, but only for left side. + + +**rtrim** _.rtrim(string, [characters]) + +Left trim. Similar to trim, but only for right side. + +**truncate** _.truncate(string, length, truncateString) + + _('Hello world').truncate(5) + => 'Hello...' + +**words** _.words(str, delimiter=" ") + +Split string by delimiter (String or RegExp), ' ' by default. + + _.words("I love you") + => ["I","love","you"] + + _.words("I_love_you", "_") + => ["I","love","you"] + + _.words("I-love-you", /-/) + => ["I","love","you"] + +**sprintf** _.sprintf(string format, *arguments) + +C like string formatting. +Credits goes to [Alexandru Marasteanu][o]. +For more detailed documentation, see the [original page][o]. + +[o]: http://www.diveintojavascript.com/projects/sprintf-for-javascript + + _.sprintf("%.1f", 1.17) + "1.2" + +**pad** _.pad(str, length, [padStr, type]) + +pads the `str` with characters until the total string length is equal to the passed `length` parameter. By default, pads on the **left** with the space char (`" "`). `padStr` is truncated to a single character if necessary. + + _.pad("1", 8) + -> " 1"; + + _.pad("1", 8, '0') + -> "00000001"; + + _.pad("1", 8, '0', 'right') + -> "10000000"; + + _.pad("1", 8, '0', 'both') + -> "00001000"; + + _.pad("1", 8, 'bleepblorp', 'both') + -> "bbbb1bbb"; + +**lpad** _.lpad(str, length, [padStr]) + +left-pad a string. Alias for `pad(str, length, padStr, 'left')` + + _.lpad("1", 8, '0') + -> "00000001"; + +**rpad** _.rpad(str, length, [padStr]) + +right-pad a string. Alias for `pad(str, length, padStr, 'right')` + + _.rpad("1", 8, '0') + -> "10000000"; + +**lrpad** _.lrpad(str, length, [padStr]) + +left/right-pad a string. Alias for `pad(str, length, padStr, 'both')` + + _.lrpad("1", 8, '0') + -> "00001000"; + +**center** alias for **lrpad** + +**ljust** alias for *lpad* + +**rjust** alias for *rpad* + +## Roadmap ## + +* Resolve problem with function names crossing between libraries (include, contains and etc). + +Any suggestions or bug reports are welcome. Just email me or more preferably open an issue. + +## Changelog ## + +### 1.1.4 ### + +* Added pad, lpad, rpad, lrpad methods and aliases center, ljust, rjust +* Integration with Underscore 1.1.6 + +### 1.1.3 ### + +* Added methods: underscored, camelize, dasherize +* Support newer version of npm + +### 1.1.2 ### + +* Created functions: lines, chars, words functions + +### 1.0.2 ### + +* Created integration test suite with underscore.js 1.1.4 (now it's absolutely compatible) +* Removed 'reverse' function, because this function override underscore.js 'reverse' + +## Contributors list ## + +* Esa-Matti Suuronen (), +* Edward Tsech , +* Sasha Koss (), +* Vladimir Dronnikov , +* Pete Kruckenberg (), +* Paul Chavard (), +* Ed Finkler () + +## Licence ## + +The MIT License + +Copyright (c) 2011 Eduard Tsech edtsech@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. + diff --git a/node_modules/underscore.string/Rakefile b/node_modules/underscore.string/Rakefile new file mode 100644 index 00000000..ae369a08 --- /dev/null +++ b/node_modules/underscore.string/Rakefile @@ -0,0 +1,8 @@ +require 'rubygems' +require 'closure-compiler' + +desc 'Use the Closure Compiler to compress Underscore.string' +task :build do + File.open('dist/underscore.string.min.js', 'w').write \ + Closure::Compiler.new.compile(File.open('lib/underscore.string.js', 'r')) +end diff --git a/node_modules/underscore.string/dist/underscore.string.min.js b/node_modules/underscore.string/dist/underscore.string.min.js new file mode 100644 index 00000000..307498bb --- /dev/null +++ b/node_modules/underscore.string/dist/underscore.string.min.js @@ -0,0 +1,9 @@ +(function(){function g(b,a){for(var c=[];a>0;c[--a]=b);return c.join("")}function f(b){if(b)return d.escapeRegExp(b);return"\\s"}var i=String.prototype.trim,d={isBlank:function(b){return!!b.match(/^\s*$/)},capitalize:function(b){return b.charAt(0).toUpperCase()+b.substring(1).toLowerCase()},chop:function(b,a){a=a||b.length;for(var c=[],d=0;d=0&&c++,e=e+(d>=0?d:0)+a.length;return c},chars:function(b){return b.split("")},escapeHTML:function(b){return String(b||"").replace(/&/g,"&").replace(//g,">")},unescapeHTML:function(b){return String(b||"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")},escapeRegExp:function(b){return String(b||"").replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1")},insert:function(b,a,c){b=b.split("");b.splice(a,0,c);return b.join("")},includes:function(b,a){return b.indexOf(a)!== +-1},join:function(b){b=String(b);for(var a="",c=1;c=a.length&&b.substring(0,a.length)===a},endsWith:function(b,a){return b.length>=a.length&&b.substring(b.length-a.length)===a},succ:function(b){var a=b.split("");a.splice(b.length-1,1,String.fromCharCode(b.charCodeAt(b.length- +1)+1));return a.join("")},titleize:function(b){b=b.split(" ");for(var a,c=0;c1&&(c=c[0]):c=" ";switch(d){case "right":e= +a-b.length;e=g(c,e);b+=e;break;case "both":e=a-b.length;e={left:g(c,Math.ceil(e/2)),right:g(c,Math.floor(e/2))};b=e.left+b+e.right;break;default:e=a-b.length,e=g(c,e),b=e+b}return b},lpad:function(b,a,c){return d.pad(b,a,c)},rpad:function(b,a,c){return d.pad(b,a,c,"right")},lrpad:function(b,a,c){return d.pad(b,a,c,"both")},sprintf:function(){for(var b=0,a,c=arguments[b++],d=[],e,h,f;c;){if(e=/^[^\x25]+/.exec(c))d.push(e[0]);else if(e=/^\x25{2}/.exec(c))d.push("%");else if(e=/^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(c)){if((a= +arguments[e[1]||b++])==null||a==void 0)throw"Too few arguments.";if(/[^s]/.test(e[7])&&typeof a!="number")throw"Expecting number but found "+typeof a;switch(e[7]){case "b":a=a.toString(2);break;case "c":a=String.fromCharCode(a);break;case "d":a=parseInt(a);break;case "e":a=e[6]?a.toExponential(e[6]):a.toExponential();break;case "f":a=e[6]?parseFloat(a).toFixed(e[6]):parseFloat(a);break;case "o":a=a.toString(8);break;case "s":a=(a=String(a))&&e[6]?a.substring(0,e[6]):a;break;case "u":a=Math.abs(a); +break;case "x":a=a.toString(16);break;case "X":a=a.toString(16).toUpperCase()}a=/[def]/.test(e[7])&&e[2]&&a>=0?"+"+a:a;h=e[3]?e[3]=="0"?"0":e[3].charAt(1):" ";f=e[5]-String(a).length-0;h=e[5]?g(h,f):"";d.push(""+(e[4]?a+h:h+a))}else throw"Huh ?!";c=c.substring(e[0].length)}return d.join("")}};d.strip=d.trim;d.lstrip=d.ltrim;d.rstrip=d.rtrim;d.center=d.lrpad;d.ljust=d.lpad;d.rjust=d.rpad;typeof window==="undefined"&&typeof module!=="undefined"?module.exports=d:typeof this._!=="undefined"?this._.mixin(d): +this._=d})(); diff --git a/node_modules/underscore.string/lib/underscore.string.js b/node_modules/underscore.string/lib/underscore.string.js new file mode 100644 index 00000000..d6722777 --- /dev/null +++ b/node_modules/underscore.string/lib/underscore.string.js @@ -0,0 +1,302 @@ +// Underscore.string +// (c) 2010 Esa-Matti Suuronen +// Underscore.strings is freely distributable under the terms of the MIT license. +// Documentation: https://github.com/edtsech/underscore.string +// Some code is borrowed from MooTools and Alexandru Marasteanu. + +// Version 1.1.4 + +(function(){ + // ------------------------- Baseline setup --------------------------------- + + // Establish the root object, "window" in the browser, or "global" on the server. + var root = this; + + var nativeTrim = String.prototype.trim; + + function str_repeat(i, m) { + for (var o = []; m > 0; o[--m] = i); + return o.join(''); + } + + function defaultToWhiteSpace(characters){ + if (characters) { + return _s.escapeRegExp(characters); + } + return '\\s'; + } + + var _s = { + + isBlank: function(str){ + return !!str.match(/^\s*$/); + }, + + capitalize : function(str) { + return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase(); + }, + + chop: function(str, step){ + step = step || str.length; + var arr = []; + for (var i = 0; i < str.length;) { + arr.push(str.slice(i,i + step)); + i = i + step; + } + return arr; + }, + + clean: function(str){ + return _s.strip(str.replace(/\s+/g, ' ')); + }, + + count: function(str, substr){ + var count = 0, index; + for (var i=0; i < str.length;) { + index = str.indexOf(substr, i); + index >= 0 && count++; + i = i + (index >= 0 ? index : 0) + substr.length; + } + return count; + }, + + chars: function(str) { + return str.split(''); + }, + + escapeHTML: function(str) { + return String(str||'').replace(/&/g,'&').replace(//g,'>'); + }, + + unescapeHTML: function(str) { + return String(str||'').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); + }, + + escapeRegExp: function(str){ + // From MooTools core 1.2.4 + return String(str||'').replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); + }, + + insert: function(str, i, substr){ + var arr = str.split(''); + arr.splice(i, 0, substr); + return arr.join(''); + }, + + includes: function(str, needle){ + return str.indexOf(needle) !== -1; + }, + + join: function(sep) { + // TODO: Could this be faster by converting + // arguments to Array and using array.join(sep)? + sep = String(sep); + var str = ""; + for (var i=1; i < arguments.length; i += 1) { + str += String(arguments[i]); + if ( i !== arguments.length-1 ) { + str += sep; + } + } + return str; + }, + + lines: function(str) { + return str.split("\n"); + }, + +// reverse: function(str){ +// return Array.prototype.reverse.apply(str.split('')).join(''); +// }, + + splice: function(str, i, howmany, substr){ + var arr = str.split(''); + arr.splice(i, howmany, substr); + return arr.join(''); + }, + + startsWith: function(str, starts){ + return str.length >= starts.length && str.substring(0, starts.length) === starts; + }, + + endsWith: function(str, ends){ + return str.length >= ends.length && str.substring(str.length - ends.length) === ends; + }, + + succ: function(str){ + var arr = str.split(''); + arr.splice(str.length-1, 1, String.fromCharCode(str.charCodeAt(str.length-1) + 1)); + return arr.join(''); + }, + + titleize: function(str){ + var arr = str.split(' '), + word; + for (var i=0; i < arr.length; i++) { + word = arr[i].split(''); + if(typeof word[0] !== 'undefined') word[0] = word[0].toUpperCase(); + i+1 === arr.length ? arr[i] = word.join('') : arr[i] = word.join('') + ' '; + } + return arr.join(''); + }, + + camelize: function(str){ + return _s.trim(str).replace(/(\-|_|\s)+(.)?/g, function(match, separator, chr) { + return chr ? chr.toUpperCase() : ''; + }); + }, + + underscored: function(str){ + return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/\-|\s+/g, '_').toLowerCase(); + }, + + dasherize: function(str){ + return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1-$2').replace(/^([A-Z]+)/, '-$1').replace(/\_|\s+/g, '-').toLowerCase(); + }, + + trim: function(str, characters){ + if (!characters && nativeTrim) { + return nativeTrim.call(str); + } + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp('\^[' + characters + ']+|[' + characters + ']+$', 'g'), ''); + }, + + ltrim: function(str, characters){ + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp('\^[' + characters + ']+', 'g'), ''); + }, + + rtrim: function(str, characters){ + characters = defaultToWhiteSpace(characters); + return str.replace(new RegExp('[' + characters + ']+$', 'g'), ''); + }, + + truncate: function(str, length, truncateStr){ + truncateStr = truncateStr || '...'; + return str.slice(0,length) + truncateStr; + }, + + words: function(str, delimiter) { + delimiter = delimiter || " "; + return str.split(delimiter); + }, + + + pad: function(str, length, padStr, type) { + + var padding = ''; + var padlen = 0; + + if (!padStr) { padStr = ' '; } + else if (padStr.length > 1) { padStr = padStr[0]; } + switch(type) { + case "right": + padlen = (length - str.length); + padding = str_repeat(padStr, padlen); + str = str+padding; + break; + case "both": + padlen = (length - str.length); + padding = { + 'left' : str_repeat(padStr, Math.ceil(padlen/2)), + 'right': str_repeat(padStr, Math.floor(padlen/2)) + }; + str = padding.left+str+padding.right; + break; + default: // "left" + padlen = (length - str.length); + padding = str_repeat(padStr, padlen);; + str = padding+str; + } + return str; + }, + + lpad: function(str, length, padStr) { + return _s.pad(str, length, padStr); + }, + + rpad: function(str, length, padStr) { + return _s.pad(str, length, padStr, 'right'); + }, + + lrpad: function(str, length, padStr) { + return _s.pad(str, length, padStr, 'both'); + }, + + + /** + * Credits for this function goes to + * http://www.diveintojavascript.com/projects/sprintf-for-javascript + * + * Copyright (c) Alexandru Marasteanu + * All rights reserved. + * */ + sprintf: function(){ + + var i = 0, a, f = arguments[i++], o = [], m, p, c, x, s = ''; + while (f) { + if (m = /^[^\x25]+/.exec(f)) { + o.push(m[0]); + } + else if (m = /^\x25{2}/.exec(f)) { + o.push('%'); + } + else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) { + if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) { + throw('Too few arguments.'); + } + if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) { + throw('Expecting number but found ' + typeof(a)); + } + switch (m[7]) { + case 'b': a = a.toString(2); break; + case 'c': a = String.fromCharCode(a); break; + case 'd': a = parseInt(a); break; + case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break; + case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break; + case 'o': a = a.toString(8); break; + case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break; + case 'u': a = Math.abs(a); break; + case 'x': a = a.toString(16); break; + case 'X': a = a.toString(16).toUpperCase(); break; + } + a = (/[def]/.test(m[7]) && m[2] && a >= 0 ? '+'+ a : a); + c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' '; + x = m[5] - String(a).length - s.length; + p = m[5] ? str_repeat(c, x) : ''; + o.push(s + (m[4] ? a + p : p + a)); + } + else { + throw('Huh ?!'); + } + f = f.substring(m[0].length); + } + return o.join(''); + } + } + + // Aliases + + _s.strip = _s.trim; + _s.lstrip = _s.ltrim; + _s.rstrip = _s.rtrim; + _s.center = _s.lrpad + _s.ljust = _s.lpad + _s.rjust = _s.rpad + + // CommonJS module is defined + if (typeof window === 'undefined' && typeof module !== 'undefined') { + // Export module + module.exports = _s; + + // Integrate with Underscore.js + } else if (typeof root._ !== 'undefined') { + root._.mixin(_s); + + // Or define it + } else { + root._ = _s; + } + +}()); diff --git a/node_modules/underscore.string/package.json b/node_modules/underscore.string/package.json new file mode 100644 index 00000000..67f429d6 --- /dev/null +++ b/node_modules/underscore.string/package.json @@ -0,0 +1,39 @@ +{ + "name": "underscore.string", + "version": "1.1.4", + "description": "String manipulation extensions for Underscore.js javascript library.", + "homepage": "https://github.com/edtsech/underscore.string", + "contributors": [ + "Esa-Matti Suuronen (http://esa-matti.suuronen.org/)", + "Edward Tsech ", + "Sasha Koss (http://koss.nocorp.me/)", + "Vladimir Dronnikov ", + "Pete Kruckenberg ()", + "Paul Chavard ()", + "Ed Finkler ()" + ], + "keywords": [ + "underscore", + "string" + ], + "main": "./lib/underscore.string", + "directories": { + "lib": "./lib" + }, + "engines": { + "node": "*" + }, + "dependencies": { + "underscore": "1.1.6" + }, + "repository": { + "type": "git", + "url": "https://github.com/edtsech/underscore.string.git" + }, + "bugs": { + "url": "https://github.com/edtsech/underscore.string/issues" + }, + "licenses" : [ + { "type" : "MIT" } + ] +} diff --git a/node_modules/underscore.string/test/speed.js b/node_modules/underscore.string/test/speed.js new file mode 100644 index 00000000..26498447 --- /dev/null +++ b/node_modules/underscore.string/test/speed.js @@ -0,0 +1,106 @@ +(function() { + + JSLitmus.test('trimNoNative', function() { + return _.trim(" foobar ", " "); + }); + + JSLitmus.test('trim', function() { + return _.trim(" foobar "); + }); + + JSLitmus.test('trim object-oriented', function() { + return _(" foobar ").trim(); + }); + + JSLitmus.test('trim jQuery', function() { + return jQuery.trim(" foobar "); + }); + + JSLitmus.test('ltrimp', function() { + return _.ltrim(" foobar ", " "); + }); + + JSLitmus.test('rtrimp', function() { + return _.rtrim(" foobar ", " "); + }); + + JSLitmus.test('startsWith', function() { + return _.startsWith("foobar", "foo"); + }); + + JSLitmus.test('endsWith', function() { + return _.endsWith("foobar", "xx"); + }); + + JSLitmus.test('chop', function(){ + return _('whitespace').chop(2); + }); + + JSLitmus.test('count', function(){ + return _('Hello worls').count('l'); + }); + + JSLitmus.test('insert', function() { + return _('Hello ').insert(6, 'world'); + }); + + JSLitmus.test('splice', function() { + return _('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'); + }); + + JSLitmus.test('succ', function(){ + var let = 'a', alphabet = []; + + for (var i=0; i < 26; i++) { + alphabet.push(let); + let = _(let).succ(); + } + + return alphabet; + }); + + JSLitmus.test('titleize', function(){ + return _('the titleize string method').titleize() + }); + + JSLitmus.test('truncate', function(){ + return _('Hello world').truncate(5); + }); + + JSLitmus.test('isBlank', function(){ + return _('').isBlank(); + }); + + JSLitmus.test('escapeHTML', function(){ + _('
    Blah blah blah
    ').escapeHTML() + }); + + JSLitmus.test('unescapeHTML', function(){ + _('<div>Blah blah blah</div>').unescapeHTML() + }); + + JSLitmus.test('reverse', function(){ + _('Hello World').reverse(); + }); + + JSLitmus.test('pad default', function(){ + _('foo').pad(12); + }); + + JSLitmus.test('pad hash left', function(){ + _('foo').pad(12, '#'); + }); + + JSLitmus.test('pad hash right', function(){ + _('foo').pad(12, '#', 'right'); + }); + + JSLitmus.test('pad hash both', function(){ + _('foo').pad(12, '#', 'both'); + }); + + JSLitmus.test('pad hash both longPad', function(){ + _('foo').pad(12, 'f00f00f00', 'both'); + }); + +})(); diff --git a/node_modules/underscore.string/test/strings.js b/node_modules/underscore.string/test/strings.js new file mode 100644 index 00000000..b6c874dd --- /dev/null +++ b/node_modules/underscore.string/test/strings.js @@ -0,0 +1,236 @@ +$(document).ready(function() { + + module("String extensions"); + + test("Strings: basic", function() { + equals(_.trim(" epeli "), "epeli", "Basic"); + equals(_.strip(" epeli "), "epeli", "Aliases"); + equals(_(" epeli ").trim(), "epeli", "Object-Oriented style"); + equals(_(" epeli ").chain().trim().capitalize().value(), "Epeli", "Can chain"); + }); + + test("Strings: capitalize", function() { + equals(_("fabio").capitalize(), "Fabio", 'First letter is upper case'); + equals(_.capitalize("fabio"), "Fabio", 'First letter is upper case'); + }); + + test("Strings: join", function() { + equals(_.join("", "foo", "bar"), "foobar", 'basic join'); + equals(_.join("", 1, "foo", 2), "1foo2", 'join numbers and strings'); + equals(_.join(" ","foo", "bar"), "foo bar", 'join with spaces'); + equals(_.join("1", "2", "2"), "212", 'join number strings'); + equals(_.join(1, 2, 2), "212", 'join numbers'); + equals(_(" ").join("foo", "bar"), "foo bar", 'join object oriented'); + }); + +// test("Strings: reverse", function() { +// equals(_.reverse("foo"), "oof" ); +// equals(_.reverse("foobar"), "raboof" ); +// equals(_.reverse("foo bar"), "rab oof" ); +// equals(_.reverse("saippuakauppias"), "saippuakauppias" ); +// }); + + test("Strings: trim", function() { + equals(_(" foo").trim(), "foo"); + equals(_("foo ").trim(), "foo"); + equals(_(" foo ").trim(), "foo"); + equals(_(" foo ").trim(), "foo"); + equals(_(" foo ", " ").trim(), "foo", "Manually set whitespace"); + + equals(_("ffoo").trim("f"), "oo"); + equals(_("ooff").trim("f"), "oo"); + equals(_("ffooff").trim("f"), "oo"); + + + equals(_("_-foobar-_").trim("_-"), "foobar"); + + equals(_("http://foo/").trim("/"), "http://foo"); + equals(_("c:\\").trim('\\'), "c:"); + }); + + test("Strings: ltrim", function() { + equals(_(" foo").ltrim(), "foo"); + equals(_(" foo").ltrim(), "foo"); + equals(_("foo ").ltrim(), "foo "); + equals(_(" foo ").ltrim(), "foo "); + + + equals(_("ffoo").ltrim("f"), "oo"); + equals(_("ooff").ltrim("f"), "ooff"); + equals(_("ffooff").ltrim("f"), "ooff"); + + equals(_("_-foobar-_").ltrim("_-"), "foobar-_"); + }); + + test("Strings: rtrim", function() { + equals(_("http://foo/").rtrim("/"), "http://foo", 'clean trailing slash'); + equals(_(" foo").rtrim(), " foo"); + equals(_("foo ").rtrim(), "foo"); + equals(_("foo ").rtrim(), "foo"); + equals(_("foo bar ").rtrim(), "foo bar"); + equals(_(" foo ").rtrim(), " foo"); + + equals(_("ffoo").rtrim("f"), "ffoo"); + equals(_("ooff").rtrim("f"), "oo"); + equals(_("ffooff").rtrim("f"), "ffoo"); + + equals(_("_-foobar-_").rtrim("_-"), "_-foobar"); + }); + + test("Strings: clean", function() { + equals(_(" foo bar ").clean(), "foo bar"); + }); + + test("Strings: sprintf", function() { + // Should be very tested function already. Thanks to + // http://www.diveintojavascript.com/projects/sprintf-for-javascript + equals(_.sprintf("Hello %s", "me"), "Hello me", 'basic'); + equals(_("Hello %s").sprintf("me"), "Hello me", 'object'); + equals(_("hello %s").chain().sprintf("me").capitalize().value(), "Hello me", 'Chaining works'); + equals(_.sprintf("%.1f", 1.22222), "1.2", 'round'); + equals(_.sprintf("%.1f", 1.17), "1.2", 'round 2'); + }); + + test("Strings: startsWith", function() { + ok(_("foobar").startsWith("foo"), 'foobar starts with foo'); + ok(!_("oobar").startsWith("foo"), 'oobar does not start with foo'); + }); + + test("Strings: endsWith", function() { + ok(_("foobar").endsWith("bar"), 'foobar ends with bar'); + ok(_.endsWith("foobar", "bar"), 'foobar ends with bar'); + ok(_.endsWith("00018-0000062.Plone.sdh264.1a7264e6912a91aa4a81b64dc5517df7b8875994.mp4", "mp4"), 'endsWith .mp4'); + ok(!_("fooba").endsWith("bar"), 'fooba does not end with bar'); + }); + + test("Strings: includes", function() { + ok(_("foobar").includes("bar"), 'foobar includes bar'); + ok(!_("foobar").includes("buzz"), 'foobar does not includes buzz'); + }); + + test('String: chop', function(){ + ok(_('whitespace').chop(2).length === 5, "output ['wh','it','es','pa','ce']"); + ok(_('whitespace').chop(3).length === 4, "output ['whi','tes','pac','e']"); + ok(_('whitespace').chop()[0].length === 10, "output ['whitespace']"); + }); + + test('String: count', function(){ + equals(_('Hello world').count('l'), 3); + equals(_('Hello world').count('Hello'), 1); + equals(_('Hello world').count('foo'), 0); + }); + + test('String: insert', function(){ + equals(_('Hello ').insert(6, 'Jessy'), 'Hello Jessy'); + }); + + test('String: splice', function(){ + equals(_('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'), + 'https://edtsech@bitbucket.org/epeli/underscore.strings'); + }); + + test('String: succ', function(){ + equals(_('a').succ(), 'b'); + equals(_('A').succ(), 'B'); + equals(_('+').succ(), ','); + }); + + test('String: titleize', function(){ + equals(_('the titleize string method').titleize(), 'The Titleize String Method'); + equals(_('the titleize string method').titleize(), 'The Titleize String Method'); + }); + + test('String: camelize', function(){ + equals(_('the_camelize_string_method').camelize(), 'theCamelizeStringMethod'); + equals(_('-the-camelize-string-method').camelize(), 'TheCamelizeStringMethod'); + equals(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); + equals(_(' the camelize string method').camelize(), 'theCamelizeStringMethod'); + equals(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); + }); + + test('String: underscored', function(){ + equals(_('the-underscored-string-method').underscored(), 'the_underscored_string_method'); + equals(_('theUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); + equals(_('TheUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); + equals(_(' the underscored string method').underscored(), 'the_underscored_string_method'); + }); + + test('String: dasherize', function(){ + equals(_('the_dasherize_string_method').dasherize(), 'the-dasherize-string-method'); + equals(_('TheDasherizeStringMethod').dasherize(), '-the-dasherize-string-method'); + equals(_('the dasherize string method').dasherize(), 'the-dasherize-string-method'); + equals(_('the dasherize string method ').dasherize(), 'the-dasherize-string-method'); + }); + + test('String: truncate', function(){ + equals(_('Hello world').truncate(6, 'read more'), 'Hello read more'); + equals(_('Hello world').truncate(5), 'Hello...'); + }); + + test('String: isBlank', function(){ + ok(_('').isBlank()); + ok(_(' ').isBlank()); + ok(_('\n').isBlank()); + ok(!_('a').isBlank()); + }); + + test('String: escapeHTML', function(){ + equals(_('
    Blah blah blah
    ').escapeHTML(), '<div>Blah blah blah</div>'); + equals(_(5).escapeHTML(), '5'); + equals(_(undefined).escapeHTML(), ''); + }); + + test('String: unescapeHTML', function(){ + equals(_('<div>Blah blah blah</div>').unescapeHTML(), '
    Blah blah blah
    '); + equals(_(5).unescapeHTML(), '5'); + equals(_(undefined).unescapeHTML(), ''); + }); + + test('String: words', function() { + equals(_("I love you!").words().length, 3); + equals(_("I_love_you!").words('_').length, 3); + equals(_("I-love-you!").words(/-/).length, 3); + }); + + test('String: chars', function() { + equals(_("Hello").chars().length, 5); + }); + + test('String: lines', function() { + equals(_("Hello\nWorld").lines().length, 2); + equals(_("Hello World").lines().length, 1); + }); + + test('String: pad', function() { + equals(_("1").pad(8), ' 1'); + equals(_("1").pad(8, '0'), '00000001'); + equals(_("1").pad(8, '0', 'left'), '00000001'); + equals(_("1").pad(8, '0', 'right'), '10000000'); + equals(_("1").pad(8, '0', 'both'), '00001000'); + equals(_("foo").pad(8, '0', 'both'), '000foo00'); + equals(_("foo").pad(7, '0', 'both'), '00foo00'); + equals(_("foo").pad(7, '!@$%dofjrofj', 'both'), '!!foo!!'); + }); + + test('String: lpad', function() { + equals(_("1").lpad(8), ' 1'); + equals(_("1").lpad(8, '0'), '00000001'); + equals(_("1").lpad(8, '0', 'left'), '00000001'); + }); + + test('String: rpad', function() { + equals(_("1").rpad(8), '1 '); + equals(_("1").rpad(8, '0'), '10000000'); + equals(_("foo").rpad(8, '0'), 'foo00000'); + equals(_("foo").rpad(7, '0'), 'foo0000'); + }); + + test('String: lrpad', function() { + equals(_("1").lrpad(8), ' 1 '); + equals(_("1").lrpad(8, '0'), '00001000'); + equals(_("foo").lrpad(8, '0'), '000foo00'); + equals(_("foo").lrpad(7, '0'), '00foo00'); + equals(_("foo").lrpad(7, '!@$%dofjrofj'), '!!foo!!'); + }); + +}); diff --git a/node_modules/underscore.string/test/test.html b/node_modules/underscore.string/test/test.html new file mode 100644 index 00000000..c928b454 --- /dev/null +++ b/node_modules/underscore.string/test/test.html @@ -0,0 +1,31 @@ + + + + Underscore.strings Test Suite + + + + + + + + + + + +

    Underscore.string Test Suite

    +

    +

    +
      +
      +

      Underscore.string Speed Suite

      + +
      + + diff --git a/node_modules/underscore.string/test/test_underscore/arrays.js b/node_modules/underscore.string/test/test_underscore/arrays.js new file mode 100644 index 00000000..e031afe9 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/arrays.js @@ -0,0 +1,124 @@ +$(document).ready(function() { + + module("Array-only functions (last, compact, uniq, and so on...)"); + + test("arrays: first", function() { + equals(_.first([1,2,3]), 1, 'can pull out the first element of an array'); + equals(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"'); + equals(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first'); + equals(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first'); + var result = (function(){ return _.first(arguments); })(4, 3, 2, 1); + equals(result, 4, 'works on an arguments object.'); + result = _.map([[1,2,3],[1,2,3]], _.first); + equals(result.join(','), '1,1', 'works well with _.map'); + }); + + test("arrays: rest", function() { + var numbers = [1, 2, 3, 4]; + equals(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()'); + equals(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)'); + equals(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index'); + var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4); + equals(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.rest); + equals(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map'); + }); + + test("arrays: last", function() { + equals(_.last([1,2,3]), 3, 'can pull out the last element of an array'); + var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4); + equals(result, 4, 'works on an arguments object'); + }); + + test("arrays: compact", function() { + equals(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values'); + var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3); + equals(result, 3, 'works on an arguments object'); + }); + + test("arrays: flatten", function() { + var list = [1, [2], [3, [[[4]]]]]; + equals(_.flatten(list).join(', '), '1, 2, 3, 4', 'can flatten nested arrays'); + var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]); + equals(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); + }); + + test("arrays: without", function() { + var list = [1, 2, 1, 0, 3, 1, 4]; + equals(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object'); + var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4); + equals(result.join(', '), '2, 3, 4', 'works on an arguments object'); + + var list = [{one : 1}, {two : 2}]; + ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.'); + ok(_.without(list, list[0]).length == 1, 'ditto.'); + }); + + test("arrays: uniq", function() { + var list = [1, 2, 1, 3, 1, 4]; + equals(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array'); + + var list = [1, 1, 1, 2, 2, 3]; + equals(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster'); + + var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4); + equals(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); + }); + + test("arrays: intersect", function() { + var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; + equals(_.intersect(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays'); + equals(_(stooges).intersect(leaders).join(''), 'moe', 'can perform an OO-style intersection'); + var result = (function(){ return _.intersect(arguments, leaders); })('moe', 'curly', 'larry'); + equals(result.join(''), 'moe', 'works on an arguments object'); + }); + + test('arrays: zip', function() { + var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true]; + var stooges = _.zip(names, ages, leaders); + equals(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths'); + }); + + test("arrays: indexOf", function() { + var numbers = [1, 2, 3]; + numbers.indexOf = null; + equals(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function'); + var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3); + equals(result, 1, 'works on an arguments object'); + equals(_.indexOf(null, 2), -1, 'handles nulls properly'); + + var numbers = [10, 20, 30, 40, 50], num = 35; + var index = _.indexOf(numbers, num, true); + equals(index, -1, '35 is not in the list'); + + numbers = [10, 20, 30, 40, 50]; num = 40; + index = _.indexOf(numbers, num, true); + equals(index, 3, '40 is in the list'); + + numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40; + index = _.indexOf(numbers, num, true); + equals(index, 1, '40 is in the list'); + }); + + test("arrays: lastIndexOf", function() { + var numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0]; + numbers.lastIndexOf = null; + equals(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function'); + equals(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); + var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0); + equals(result, 5, 'works on an arguments object'); + equals(_.indexOf(null, 2), -1, 'handles nulls properly'); + }); + + test("arrays: range", function() { + equals(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array'); + equals(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); + equals(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1'); + equals(_.range(8, 5).join(''), '', 'range with two arguments a & b, b<a generates an empty array'); + equals(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c'); + equals(_.range(3, 10, 15).join(''), '3', 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a'); + equals(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b'); + equals(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs'); + }); + +}); diff --git a/node_modules/underscore.string/test/test_underscore/chaining.js b/node_modules/underscore.string/test/test_underscore/chaining.js new file mode 100644 index 00000000..e633ba5a --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/chaining.js @@ -0,0 +1,47 @@ +$(document).ready(function() { + + module("Underscore chaining."); + + test("chaining: map/flatten/reduce", function() { + var lyrics = [ + "I'm a lumberjack and I'm okay", + "I sleep all night and I work all day", + "He's a lumberjack and he's okay", + "He sleeps all night and he works all day" + ]; + var counts = _(lyrics).chain() + .map(function(line) { return line.split(''); }) + .flatten() + .reduce(function(hash, l) { + hash[l] = hash[l] || 0; + hash[l]++; + return hash; + }, {}).value(); + ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song'); + }); + + test("chaining: select/reject/sortBy", function() { + var numbers = [1,2,3,4,5,6,7,8,9,10]; + numbers = _(numbers).chain().select(function(n) { + return n % 2 == 0; + }).reject(function(n) { + return n % 4 == 0; + }).sortBy(function(n) { + return -n; + }).value(); + equals(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + }); + + test("chaining: reverse/concat/unshift/pop/map", function() { + var numbers = [1,2,3,4,5]; + numbers = _(numbers).chain() + .reverse() + .concat([5, 5, 5]) + .unshift(17) + .pop() + .map(function(n){ return n * 2; }) + .value(); + equals(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.'); + }); + +}); diff --git a/node_modules/underscore.string/test/test_underscore/collections.js b/node_modules/underscore.string/test/test_underscore/collections.js new file mode 100644 index 00000000..ff365f8e --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/collections.js @@ -0,0 +1,207 @@ +$(document).ready(function() { + + module("Collection functions (each, any, select, and so on...)"); + + test("collections: each", function() { + _.each([1, 2, 3], function(num, i) { + equals(num, i + 1, 'each iterators provide value and iteration count'); + }); + + var answers = []; + _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5}); + equals(answers.join(', '), '5, 10, 15', 'context object property accessed'); + + answers = []; + _.forEach([1, 2, 3], function(num){ answers.push(num); }); + equals(answers.join(', '), '1, 2, 3', 'aliased as "forEach"'); + + answers = []; + var obj = {one : 1, two : 2, three : 3}; + obj.constructor.prototype.four = 4; + _.each(obj, function(value, key){ answers.push(key); }); + equals(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.'); + delete obj.constructor.prototype.four; + + answer = null; + _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; }); + ok(answer, 'can reference the original collection from inside the iterator'); + + answers = []; + _.each({range : 1, speed : 2, length : 3}, function(v){ answers.push(v); }); + ok(answers.join(', '), '1, 2, 3', 'can iterate over objects with numeric length properties'); + + answers = 0; + _.each(null, function(){ ++answers; }); + equals(answers, 0, 'handles a null properly'); + }); + + test('collections: map', function() { + var doubled = _.map([1, 2, 3], function(num){ return num * 2; }); + equals(doubled.join(', '), '2, 4, 6', 'doubled numbers'); + + var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3}); + equals(tripled.join(', '), '3, 6, 9', 'tripled numbers with context'); + + var doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); + equals(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers'); + + var ids = _.map(document.body.childNodes, function(n){ return n.id; }); + ok(_.include(ids, 'qunit-header'), 'can use collection methods on NodeLists'); + + var ids = _.map(document.images, function(n){ return n.id; }); + ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections'); + + var ifnull = _.map(null, function(){}); + ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly'); + }); + + test('collections: reduce', function() { + var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0); + equals(sum, 6, 'can sum up an array'); + + var context = {multiplier : 3}; + sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context); + equals(sum, 18, 'can reduce with a context object'); + + sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0); + equals(sum, 6, 'aliased as "inject"'); + + sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0); + equals(sum, 6, 'OO-style reduce'); + + var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }); + equals(sum, 6, 'default initial value'); + + var ifnull; + try { + _.reduce(null, function(){}); + } catch (ex) { + ifnull = ex; + } + ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); + + ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + }); + + test('collections: reduceRight', function() { + var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); + equals(list, 'bazbarfoo', 'can perform right folds'); + + var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); + equals(list, 'bazbarfoo', 'aliased as "foldr"'); + + var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }); + equals(list, 'bazbarfoo', 'default initial value'); + + var ifnull; + try { + _.reduceRight(null, function(){}); + } catch (ex) { + ifnull = ex; + } + ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); + + ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + }); + + test('collections: detect', function() { + var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; }); + equals(result, 2, 'found the first "2" and broke the loop'); + }); + + test('collections: select', function() { + var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equals(evens.join(', '), '2, 4, 6', 'selected each even number'); + + evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equals(evens.join(', '), '2, 4, 6', 'aliased as "filter"'); + }); + + test('collections: reject', function() { + var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equals(odds.join(', '), '1, 3, 5', 'rejected each even number'); + }); + + test('collections: all', function() { + ok(_.all([], _.identity), 'the empty set'); + ok(_.all([true, true, true], _.identity), 'all true values'); + ok(!_.all([true, false, true], _.identity), 'one false value'); + ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers'); + ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number'); + ok(_.every([true, true, true], _.identity), 'aliased as "every"'); + }); + + test('collections: any', function() { + ok(!_.any([]), 'the empty set'); + ok(!_.any([false, false, false]), 'all false values'); + ok(_.any([false, false, true]), 'one true value'); + ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers'); + ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number'); + ok(_.some([false, false, true]), 'aliased as "some"'); + }); + + test('collections: include', function() { + ok(_.include([1,2,3], 2), 'two is in the array'); + ok(!_.include([1,3,9], 2), 'two is not in the array'); + ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values'); + ok(_([1,2,3]).include(2), 'OO-style include'); + }); + + test('collections: invoke', function() { + var list = [[5, 1, 7], [3, 2, 1]]; + var result = _.invoke(list, 'sort'); + equals(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equals(result[1].join(', '), '1, 2, 3', 'second array sorted'); + }); + + test('collections: invoke w/ function reference', function() { + var list = [[5, 1, 7], [3, 2, 1]]; + var result = _.invoke(list, Array.prototype.sort); + equals(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equals(result[1].join(', '), '1, 2, 3', 'second array sorted'); + }); + + test('collections: pluck', function() { + var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}]; + equals(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects'); + }); + + test('collections: max', function() { + equals(3, _.max([1, 2, 3]), 'can perform a regular Math.max'); + + var neg = _.max([1, 2, 3], function(num){ return -num; }); + equals(neg, 1, 'can perform a computation-based max'); + }); + + test('collections: min', function() { + equals(1, _.min([1, 2, 3]), 'can perform a regular Math.min'); + + var neg = _.min([1, 2, 3], function(num){ return -num; }); + equals(neg, 3, 'can perform a computation-based min'); + }); + + test('collections: sortBy', function() { + var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}]; + people = _.sortBy(people, function(person){ return person.age; }); + equals(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age'); + }); + + test('collections: sortedIndex', function() { + var numbers = [10, 20, 30, 40, 50], num = 35; + var index = _.sortedIndex(numbers, num); + equals(index, 3, '35 should be inserted at index 3'); + }); + + test('collections: toArray', function() { + ok(!_.isArray(arguments), 'arguments object is not an array'); + ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array'); + + var numbers = _.toArray({one : 1, two : 2, three : 3}); + equals(numbers.join(', '), '1, 2, 3', 'object flattened into array'); + }); + + test('collections: size', function() { + equals(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object'); + }); + +}); diff --git a/node_modules/underscore.string/test/test_underscore/functions.js b/node_modules/underscore.string/test/test_underscore/functions.js new file mode 100644 index 00000000..95267e73 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/functions.js @@ -0,0 +1,154 @@ +$(document).ready(function() { + + module("Function functions (bind, bindAll, and so on...)"); + + test("functions: bind", function() { + var context = {name : 'moe'}; + var func = function(arg) { return "name: " + (this.name || arg); }; + var bound = _.bind(func, context); + equals(bound(), 'name: moe', 'can bind a function to a context'); + + bound = _(func).bind(context); + equals(bound(), 'name: moe', 'can do OO-style binding'); + + bound = _.bind(func, null, 'curly'); + equals(bound(), 'name: curly', 'can bind without specifying a context'); + + func = function(salutation, name) { return salutation + ': ' + name; }; + func = _.bind(func, this, 'hello'); + equals(func('moe'), 'hello: moe', 'the function was partially applied in advance'); + + var func = _.bind(func, this, 'curly'); + equals(func(), 'hello: curly', 'the function was completely applied in advance'); + + var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; }; + func = _.bind(func, this, 'hello', 'moe', 'curly'); + equals(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); + + func = function(context, message) { equals(this, context, message); }; + _.bind(func, 0, 0, 'can bind a function to `0`')(); + _.bind(func, '', '', 'can bind a function to an empty string')(); + _.bind(func, false, false, 'can bind a function to `false`')(); + }); + + test("functions: bindAll", function() { + var curly = {name : 'curly'}, moe = { + name : 'moe', + getName : function() { return 'name: ' + this.name; }, + sayHi : function() { return 'hi: ' + this.name; } + }; + curly.getName = moe.getName; + _.bindAll(moe, 'getName', 'sayHi'); + curly.sayHi = moe.sayHi; + equals(curly.getName(), 'name: curly', 'unbound function is bound to current object'); + equals(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object'); + + curly = {name : 'curly'}; + moe = { + name : 'moe', + getName : function() { return 'name: ' + this.name; }, + sayHi : function() { return 'hi: ' + this.name; } + }; + _.bindAll(moe); + curly.sayHi = moe.sayHi; + equals(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object'); + }); + + test("functions: memoize", function() { + var fib = function(n) { + return n < 2 ? n : fib(n - 1) + fib(n - 2); + }; + var fastFib = _.memoize(fib); + equals(fib(10), 55, 'a memoized version of fibonacci produces identical results'); + equals(fastFib(10), 55, 'a memoized version of fibonacci produces identical results'); + + var o = function(str) { + return str; + }; + var fastO = _.memoize(o); + equals(o('toString'), 'toString', 'checks hasOwnProperty'); + equals(fastO('toString'), 'toString', 'checks hasOwnProperty'); + }); + + asyncTest("functions: delay", 2, function() { + var delayed = false; + _.delay(function(){ delayed = true; }, 100); + _.delay(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50); + _.delay(function(){ ok(delayed, 'delayed the function'); start(); }, 150); + }); + + asyncTest("functions: defer", 1, function() { + var deferred = false; + _.defer(function(bool){ deferred = bool; }, true); + _.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50); + }); + + asyncTest("functions: throttle", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + throttledIncr(); throttledIncr(); throttledIncr(); + setTimeout(throttledIncr, 120); + setTimeout(throttledIncr, 140); + setTimeout(throttledIncr, 220); + setTimeout(throttledIncr, 240); + _.delay(function(){ ok(counter == 3, "incr was throttled"); start(); }, 400); + }); + + asyncTest("functions: debounce", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var debouncedIncr = _.debounce(incr, 50); + debouncedIncr(); debouncedIncr(); debouncedIncr(); + setTimeout(debouncedIncr, 30); + setTimeout(debouncedIncr, 60); + setTimeout(debouncedIncr, 90); + setTimeout(debouncedIncr, 120); + setTimeout(debouncedIncr, 150); + _.delay(function(){ ok(counter == 1, "incr was debounced"); start(); }, 220); + }); + + test("functions: once", function() { + var num = 0; + var increment = _.once(function(){ num++; }); + increment(); + increment(); + equals(num, 1); + }); + + test("functions: wrap", function() { + var greet = function(name){ return "hi: " + name; }; + var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); }); + equals(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function'); + + var inner = function(){ return "Hello "; }; + var obj = {name : "Moe"}; + obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; }); + equals(obj.hi(), "Hello Moe"); + }); + + test("functions: compose", function() { + var greet = function(name){ return "hi: " + name; }; + var exclaim = function(sentence){ return sentence + '!'; }; + var composed = _.compose(exclaim, greet); + equals(composed('moe'), 'hi: moe!', 'can compose a function that takes another'); + + composed = _.compose(greet, exclaim); + equals(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); + }); + + test("functions: after", function() { + var testAfter = function(afterAmount, timesCalled) { + var afterCalled = 0; + var after = _.after(afterAmount, function() { + afterCalled++; + }); + while (timesCalled--) after(); + return afterCalled; + }; + + equals(testAfter(5, 5), 1, "after(N) should fire after being called N times"); + equals(testAfter(5, 4), 0, "after(N) should not fire unless called N times"); + }); + +}); diff --git a/node_modules/underscore.string/test/test_underscore/objects.js b/node_modules/underscore.string/test/test_underscore/objects.js new file mode 100644 index 00000000..93c44117 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/objects.js @@ -0,0 +1,246 @@ +$(document).ready(function() { + + module("Object functions (values, extend, isEqual, and so on...)"); + + test("objects: keys", function() { + var exception = /object/; + equals(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object'); + // the test above is not safe because it relies on for-in enumeration order + var a = []; a[1] = 0; + equals(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95'); + raises(function() { _.keys(null); }, exception, 'throws an error for `null` values'); + raises(function() { _.keys(void 0); }, exception, 'throws an error for `undefined` values'); + raises(function() { _.keys(1); }, exception, 'throws an error for number primitives'); + raises(function() { _.keys('a'); }, exception, 'throws an error for string primitives'); + raises(function() { _.keys(true); }, exception, 'throws an error for boolean primitives'); + }); + + test("objects: values", function() { + equals(_.values({one : 1, two : 2}).join(', '), '1, 2', 'can extract the values from an object'); + }); + + test("objects: functions", function() { + var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce}; + ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object'); + }); + + test("objects: extend", function() { + var result; + equals(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another'); + equals(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination'); + equals(_.extend({x:'x'}, {a:'b'}).x, 'x', 'properties not in source dont get overriden'); + result = _.extend({x:'x'}, {a:'a'}, {b:'b'}); + ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects'); + result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'}); + ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps'); + result = _.extend({}, {a: void 0, b: null}); + equals(_.keys(result).join(''), 'b', 'extend does not copy undefined values'); + }); + + test("objects: defaults", function() { + var result; + var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"}; + + _.defaults(options, {zero: 1, one: 10, twenty: 20}); + equals(options.zero, 0, 'value exists'); + equals(options.one, 1, 'value exists'); + equals(options.twenty, 20, 'default applied'); + + _.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"}); + equals(options.empty, "", 'value exists'); + ok(_.isNaN(options.nan), "NaN isn't overridden"); + equals(options.word, "word", 'new value is added, first one wins'); + }); + + test("objects: clone", function() { + var moe = {name : 'moe', lucky : [13, 27, 34]}; + var clone = _.clone(moe); + equals(clone.name, 'moe', 'the clone as the attributes of the original'); + + clone.name = 'curly'; + ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original'); + + clone.lucky.push(101); + equals(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original'); + }); + + test("objects: isEqual", function() { + var moe = {name : 'moe', lucky : [13, 27, 34]}; + var clone = {name : 'moe', lucky : [13, 27, 34]}; + ok(moe != clone, 'basic equality between objects is false'); + ok(_.isEqual(moe, clone), 'deep equality is true'); + ok(_(moe).isEqual(clone), 'OO-style deep equality works'); + ok(!_.isEqual(5, NaN), '5 is not equal to NaN'); + ok(NaN != NaN, 'NaN is not equal to NaN (native equality)'); + ok(NaN !== NaN, 'NaN is not equal to NaN (native identity)'); + ok(!_.isEqual(NaN, NaN), 'NaN is not equal to NaN'); + ok(_.isEqual(new Date(100), new Date(100)), 'identical dates are equal'); + ok(_.isEqual((/hello/ig), (/hello/ig)), 'identical regexes are equal'); + ok(!_.isEqual(null, [1]), 'a falsy is never equal to a truthy'); + ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), 'objects with the same number of undefined keys are not equal'); + ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'wrapped objects are not equal'); + equals(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, 'wrapped objects are equal'); + }); + + test("objects: isEmpty", function() { + ok(!_([1]).isEmpty(), '[1] is not empty'); + ok(_.isEmpty([]), '[] is empty'); + ok(!_.isEmpty({one : 1}), '{one : 1} is not empty'); + ok(_.isEmpty({}), '{} is empty'); + ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty'); + ok(_.isEmpty(null), 'null is empty'); + ok(_.isEmpty(), 'undefined is empty'); + ok(_.isEmpty(''), 'the empty string is empty'); + ok(!_.isEmpty('moe'), 'but other strings are not'); + + var obj = {one : 1}; + delete obj.one; + ok(_.isEmpty(obj), 'deleting all the keys from an object empties it'); + }); + + // Setup remote variables for iFrame tests. + var iframe = document.createElement('iframe'); + jQuery(iframe).appendTo(document.body); + var iDoc = iframe.contentDocument || iframe.contentWindow.document; + iDoc.write( + "" + ); + iDoc.close(); + + test("objects: isElement", function() { + ok(!_.isElement('div'), 'strings are not dom elements'); + ok(_.isElement($('html')[0]), 'the html tag is a DOM element'); + ok(_.isElement(iElement), 'even from another frame'); + }); + + test("objects: isArguments", function() { + var args = (function(){ return arguments; })(1, 2, 3); + ok(!_.isArguments('string'), 'a string is not an arguments object'); + ok(!_.isArguments(_.isArguments), 'a function is not an arguments object'); + ok(_.isArguments(args), 'but the arguments object is an arguments object'); + ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); + ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.'); + ok(_.isArguments(iArguments), 'even from another frame'); + }); + + test("objects: isArray", function() { + ok(!_.isArray(arguments), 'the arguments object is not an array'); + ok(_.isArray([1, 2, 3]), 'but arrays are'); + ok(_.isArray(iArray), 'even from another frame'); + }); + + test("objects: isString", function() { + ok(!_.isString(document.body), 'the document body is not a string'); + ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); + ok(_.isString(iString), 'even from another frame'); + }); + + test("objects: isNumber", function() { + ok(!_.isNumber('string'), 'a string is not a number'); + ok(!_.isNumber(arguments), 'the arguments object is not a number'); + ok(!_.isNumber(undefined), 'undefined is not a number'); + ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); + ok(!_.isNumber(NaN), 'NaN is not a number'); + ok(_.isNumber(Infinity), 'Infinity is a number'); + ok(_.isNumber(iNumber), 'even from another frame'); + }); + + test("objects: isBoolean", function() { + ok(!_.isBoolean(2), 'a number is not a boolean'); + ok(!_.isBoolean("string"), 'a string is not a boolean'); + ok(!_.isBoolean("false"), 'the string "false" is not a boolean'); + ok(!_.isBoolean("true"), 'the string "true" is not a boolean'); + ok(!_.isBoolean(arguments), 'the arguments object is not a boolean'); + ok(!_.isBoolean(undefined), 'undefined is not a boolean'); + ok(!_.isBoolean(NaN), 'NaN is not a boolean'); + ok(!_.isBoolean(null), 'null is not a boolean'); + ok(_.isBoolean(true), 'but true is'); + ok(_.isBoolean(false), 'and so is false'); + ok(_.isBoolean(iBoolean), 'even from another frame'); + }); + + test("objects: isFunction", function() { + ok(!_.isFunction([1, 2, 3]), 'arrays are not functions'); + ok(!_.isFunction('moe'), 'strings are not functions'); + ok(_.isFunction(_.isFunction), 'but functions are'); + ok(_.isFunction(iFunction), 'even from another frame'); + }); + + test("objects: isDate", function() { + ok(!_.isDate(100), 'numbers are not dates'); + ok(!_.isDate({}), 'objects are not dates'); + ok(_.isDate(new Date()), 'but dates are'); + ok(_.isDate(iDate), 'even from another frame'); + }); + + test("objects: isRegExp", function() { + ok(!_.isRegExp(_.identity), 'functions are not RegExps'); + ok(_.isRegExp(/identity/), 'but RegExps are'); + ok(_.isRegExp(iRegExp), 'even from another frame'); + }); + + test("objects: isNaN", function() { + ok(!_.isNaN(undefined), 'undefined is not NaN'); + ok(!_.isNaN(null), 'null is not NaN'); + ok(!_.isNaN(0), '0 is not NaN'); + ok(_.isNaN(NaN), 'but NaN is'); + ok(_.isNaN(iNaN), 'even from another frame'); + }); + + test("objects: isNull", function() { + ok(!_.isNull(undefined), 'undefined is not null'); + ok(!_.isNull(NaN), 'NaN is not null'); + ok(_.isNull(null), 'but null is'); + ok(_.isNull(iNull), 'even from another frame'); + }); + + test("objects: isUndefined", function() { + ok(!_.isUndefined(1), 'numbers are defined'); + ok(!_.isUndefined(null), 'null is defined'); + ok(!_.isUndefined(false), 'false is defined'); + ok(!_.isUndefined(NaN), 'NaN is defined'); + ok(_.isUndefined(), 'nothing is undefined'); + ok(_.isUndefined(undefined), 'undefined is undefined'); + ok(_.isUndefined(iUndefined), 'even from another frame'); + }); + + if (window.ActiveXObject) { + test("objects: IE host objects", function() { + var xml = new ActiveXObject("Msxml2.DOMDocument.3.0"); + ok(!_.isNumber(xml)); + ok(!_.isBoolean(xml)); + ok(!_.isNaN(xml)); + ok(!_.isFunction(xml)); + ok(!_.isNull(xml)); + ok(!_.isUndefined(xml)); + }); + } + + test("objects: tap", function() { + var intercepted = null; + var interceptor = function(obj) { intercepted = obj; }; + var returned = _.tap(1, interceptor); + equals(intercepted, 1, "passes tapped object to interceptor"); + equals(returned, 1, "returns tapped object"); + + returned = _([1,2,3]).chain(). + map(function(n){ return n * 2; }). + max(). + tap(interceptor). + value(); + ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain'); + }); +}); diff --git a/node_modules/underscore.string/test/test_underscore/speed.js b/node_modules/underscore.string/test/test_underscore/speed.js new file mode 100644 index 00000000..86663a23 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/speed.js @@ -0,0 +1,70 @@ +(function() { + + var numbers = []; + for (var i=0; i<1000; i++) numbers.push(i); + var objects = _.map(numbers, function(n){ return {num : n}; }); + var randomized = _.sortBy(numbers, function(){ return Math.random(); }); + + JSLitmus.test('_.each()', function() { + var timesTwo = []; + _.each(numbers, function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('_(list).each()', function() { + var timesTwo = []; + _(numbers).each(function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('jQuery.each()', function() { + var timesTwo = []; + jQuery.each(numbers, function(){ timesTwo.push(this * 2); }); + return timesTwo; + }); + + JSLitmus.test('_.map()', function() { + return _.map(objects, function(obj){ return obj.num; }); + }); + + JSLitmus.test('jQuery.map()', function() { + return jQuery.map(objects, function(obj){ return obj.num; }); + }); + + JSLitmus.test('_.pluck()', function() { + return _.pluck(objects, 'num'); + }); + + JSLitmus.test('_.uniq()', function() { + return _.uniq(randomized); + }); + + JSLitmus.test('_.uniq() (sorted)', function() { + return _.uniq(numbers, true); + }); + + JSLitmus.test('_.sortBy()', function() { + return _.sortBy(numbers, function(num){ return -num; }); + }); + + JSLitmus.test('_.isEqual()', function() { + return _.isEqual(numbers, randomized); + }); + + JSLitmus.test('_.keys()', function() { + return _.keys(objects); + }); + + JSLitmus.test('_.values()', function() { + return _.values(objects); + }); + + JSLitmus.test('_.intersect()', function() { + return _.intersect(numbers, randomized); + }); + + JSLitmus.test('_.range()', function() { + return _.range(1000); + }); + +})(); \ No newline at end of file diff --git a/node_modules/underscore.string/test/test_underscore/temp.js b/node_modules/underscore.string/test/test_underscore/temp.js new file mode 100644 index 00000000..68c39dc5 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/temp.js @@ -0,0 +1,27 @@ +(function() { + + var func = function(){}; + var date = new Date(); + var str = "a string"; + var numbers = []; + for (var i=0; i<1000; i++) numbers.push(i); + var objects = _.map(numbers, function(n){ return {num : n}; }); + var randomized = _.sortBy(numbers, function(){ return Math.random(); }); + + JSLitmus.test('_.isNumber', function() { + return _.isNumber(1000) + }); + + JSLitmus.test('_.newIsNumber', function() { + return _.newIsNumber(1000) + }); + + JSLitmus.test('_.isNumber(NaN)', function() { + return _.isNumber(NaN) + }); + + JSLitmus.test('_.newIsNumber(NaN)', function() { + return _.newIsNumber(NaN) + }); + +})(); \ No newline at end of file diff --git a/node_modules/underscore.string/test/test_underscore/temp_tests.html b/node_modules/underscore.string/test/test_underscore/temp_tests.html new file mode 100644 index 00000000..bd34f9dd --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/temp_tests.html @@ -0,0 +1,19 @@ + + + + Underscore Temporary Tests + + + + + + + +

      Underscore Temporary Tests

      +

      + A page for temporary speed tests, used for developing faster implementations + of existing Underscore methods. +

      +
      + + diff --git a/node_modules/underscore.string/test/test_underscore/test.html b/node_modules/underscore.string/test/test_underscore/test.html new file mode 100644 index 00000000..65ba7c3a --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/test.html @@ -0,0 +1,42 @@ + + + + Underscore Test Suite + + + + + + + + + + + + + + + +

      Underscore Test Suite

      +

      +

      +
        +
        +

        Underscore Speed Suite

        +

        + A representative sample of the functions are benchmarked here, to provide + a sense of how fast they might run in different browsers. + Each iteration runs on an array of 1000 elements.

        + For example, the 'intersect' test measures the number of times you can + find the intersection of two thousand-element arrays in one second. +

        +
        + + + + + diff --git a/node_modules/underscore.string/test/test_underscore/utility.js b/node_modules/underscore.string/test/test_underscore/utility.js new file mode 100644 index 00000000..94252a65 --- /dev/null +++ b/node_modules/underscore.string/test/test_underscore/utility.js @@ -0,0 +1,127 @@ +$(document).ready(function() { + + module("Utility functions (uniqueId, template)"); + + test("utility: noConflict", function() { + var underscore = _.noConflict(); + ok(underscore.isUndefined(_), "The '_' variable has been returned to its previous state."); + var intersection = underscore.intersect([-1, 0, 1, 2], [1, 2, 3, 4]); + equals(intersection.join(', '), '1, 2', 'but the intersection function still works'); + window._ = underscore; + }); + + test("utility: identity", function() { + var moe = {name : 'moe'}; + equals(_.identity(moe), moe, 'moe is the same as his identity'); + }); + + test("utility: uniqueId", function() { + var ids = [], i = 0; + while(i++ < 100) ids.push(_.uniqueId()); + equals(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); + }); + + test("utility: times", function() { + var vals = []; + _.times(3, function (i) { vals.push(i); }); + ok(_.isEqual(vals, [0,1,2]), "is 0 indexed"); + // + vals = []; + _(3).times(function (i) { vals.push(i); }); + ok(_.isEqual(vals, [0,1,2]), "works as a wrapper"); + }); + + test("utility: mixin", function() { + _.mixin({ + myReverse: function(string) { + return string.split('').reverse().join(''); + } + }); + equals(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); + equals(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); + }); + + test("utility: template", function() { + var basicTemplate = _.template("<%= thing %> is gettin' on my noives!"); + var result = basicTemplate({thing : 'This'}); + equals(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); + + var backslashTemplate = _.template("<%= thing %> is \\ridanculous"); + equals(backslashTemplate({thing: 'This'}), "This is \\ridanculous"); + + var fancyTemplate = _.template("
          <% \ + for (key in people) { \ + %>
        • <%= people[key] %>
        • <% } %>
        "); + result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); + equals(result, "
        • Moe
        • Larry
        • Curly
        ", 'can run arbitrary javascript in templates'); + + var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
        \">
        <% }); %>"); + result = namespaceCollisionTemplate({ + pageCount: 3, + thumbnails: { + 1: "p1-thumbnail.gif", + 2: "p2-thumbnail.gif", + 3: "p3-thumbnail.gif" + } + }); + equals(result, "3 p3-thumbnail.gif
        "); + + var noInterpolateTemplate = _.template("

        Just some text. Hey, I know this is silly but it aids consistency.

        "); + result = noInterpolateTemplate(); + equals(result, "

        Just some text. Hey, I know this is silly but it aids consistency.

        "); + + var quoteTemplate = _.template("It's its, not it's"); + equals(quoteTemplate({}), "It's its, not it's"); + + var quoteInStatementAndBody = _.template("<%\ + if(foo == 'bar'){ \ + %>Statement quotes and 'quotes'.<% } %>"); + equals(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); + + var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.'); + equals(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); + + if (!$.browser.msie) { + var fromHTML = _.template($('#template').html()); + equals(fromHTML({data : 12345}).replace(/\s/g, ''), '
      1. 24690
      2. '); + } + + _.templateSettings = { + evaluate : /\{\{([\s\S]+?)\}\}/g, + interpolate : /\{\{=([\s\S]+?)\}\}/g + }; + + var custom = _.template("
          {{ for (key in people) { }}
        • {{= people[key] }}
        • {{ } }}
        "); + result = custom({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); + equals(result, "
        • Moe
        • Larry
        • Curly
        ", 'can run arbitrary javascript in templates'); + + var customQuote = _.template("It's its, not it's"); + equals(customQuote({}), "It's its, not it's"); + + var quoteInStatementAndBody = _.template("{{ if(foo == 'bar'){ }}Statement quotes and 'quotes'.{{ } }}"); + equals(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); + + _.templateSettings = { + evaluate : /<\?([\s\S]+?)\?>/g, + interpolate : /<\?=([\s\S]+?)\?>/g + }; + + var customWithSpecialChars = _.template("
        "); + result = customWithSpecialChars({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); + equals(result, "
        • Moe
        • Larry
        • Curly
        ", 'can run arbitrary javascript in templates'); + + var customWithSpecialCharsQuote = _.template("It's its, not it's"); + equals(customWithSpecialCharsQuote({}), "It's its, not it's"); + + var quoteInStatementAndBody = _.template("Statement quotes and 'quotes'."); + equals(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); + + _.templateSettings = { + interpolate : /\{\{(.+?)\}\}/g + }; + + var mustache = _.template("Hello {{planet}}!"); + equals(mustache({planet : "World"}), "Hello World!", "can mimic mustache.js"); + }); + +}); diff --git a/node_modules/underscore.string/test/underscore.js b/node_modules/underscore.string/test/underscore.js new file mode 100644 index 00000000..eaba008c --- /dev/null +++ b/node_modules/underscore.string/test/underscore.js @@ -0,0 +1,807 @@ +// Underscore.js 1.1.6 +// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `global` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Establish the object that gets returned to break out of a loop iteration. + var breaker = {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var slice = ArrayProto.slice, + unshift = ArrayProto.unshift, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { return new wrapper(obj); }; + + // Export the Underscore object for **CommonJS**, with backwards-compatibility + // for the old `require()` API. If we're not in CommonJS, add `_` to the + // global object. + if (typeof module !== 'undefined' && module.exports) { + module.exports = _; + _._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.1.6'; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles objects implementing `forEach`, arrays, and raw objects. + // Delegates to **ECMAScript 5**'s native `forEach` if available. + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (_.isNumber(obj.length)) { + for (var i = 0, l = obj.length; i < l; i++) { + if (iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + for (var key in obj) { + if (hasOwnProperty.call(obj, key)) { + if (iterator.call(context, obj[key], key, obj) === breaker) return; + } + } + } + }; + + // Return the results of applying the iterator to each element. + // Delegates to **ECMAScript 5**'s native `map` if available. + _.map = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results[results.length] = iterator.call(context, value, index, list); + }); + return results; + }; + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = memo !== void 0; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial && index === 0) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError("Reduce of empty array with no initial value"); + return memo; + }; + + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse(); + return _.reduce(reversed, iterator, memo, context); + }; + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, iterator, context) { + var result; + any(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); + each(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + each(obj, function(value, index, list) { + if (!iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, iterator, context) { + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); + each(obj, function(value, index, list) { + if (!(result = result && iterator.call(context, value, index, list))) return breaker; + }); + return result; + }; + + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); + each(obj, function(value, index, list) { + if (result = iterator.call(context, value, index, list)) return breaker; + }); + return result; + }; + + // Determine if a given value is included in the array or object using `===`. + // Aliased as `contains`. + _.include = _.contains = function(obj, target) { + var found = false; + if (obj == null) return found; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + any(obj, function(value) { + if (found = value === target) return true; + }); + return found; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + return _.map(obj, function(value) { + return (method.call ? method || value : value[method]).apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, function(value){ return value[key]; }); + }; + + // Return the maximum element or (element-based computation). + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); + var result = {computed : -Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed >= result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); + var result = {computed : Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed < result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, iterator, context) { + return _.pluck(_.map(obj, function(value, index, list) { + return { + value : value, + criteria : iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }), 'value'); + }; + + // Use a comparator function to figure out at what index an object should + // be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator) { + iterator || (iterator = _.identity); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >> 1; + iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; + } + return low; + }; + + // Safely convert anything iterable into a real, live array. + _.toArray = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) return iterable.toArray(); + if (_.isArray(iterable)) return iterable; + if (_.isArguments(iterable)) return slice.call(iterable); + return _.values(iterable); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + return _.toArray(obj).length; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head`. The **guard** check allows it to work + // with `_.map`. + _.first = _.head = function(array, n, guard) { + return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; + }; + + // Returns everything but the first entry of the array. Aliased as `tail`. + // Especially useful on the arguments object. Passing an **index** will return + // the rest of the values in the array from that index onward. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = function(array, index, guard) { + return slice.call(array, (index == null) || guard ? 1 : index); + }; + + // Get the last element of an array. + _.last = function(array) { + return array[array.length - 1]; + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, function(value){ return !!value; }); + }; + + // Return a completely flattened version of an array. + _.flatten = function(array) { + return _.reduce(array, function(memo, value) { + if (_.isArray(value)) return memo.concat(_.flatten(value)); + memo[memo.length] = value; + return memo; + }, []); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + var values = slice.call(arguments, 1); + return _.filter(array, function(value){ return !_.include(values, value); }); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted) { + return _.reduce(array, function(memo, el, i) { + if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el; + return memo; + }, []); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersect = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.indexOf(other, item) >= 0; + }); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var args = slice.call(arguments); + var length = _.max(_.pluck(args, 'length')); + var results = new Array(length); + for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); + return results; + }; + + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i, l; + if (isSorted) { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); + for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i; + return -1; + }; + + + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item) { + if (array == null) return -1; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); + var i = array.length; + while (i--) if (array[i] === item) return i; + return -1; + }; + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var len = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(len); + + while(idx < len) { + range[idx++] = start; + start += step; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Binding with arguments is also known as `curry`. + // Delegates to **ECMAScript 5**'s native `Function.bind` if available. + // We check for `func.bind` first, to fail fast when `func` is undefined. + _.bind = function(func, obj) { + if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + var args = slice.call(arguments, 2); + return function() { + return func.apply(obj, args.concat(slice.call(arguments))); + }; + }; + + // Bind all of an object's methods to that object. Useful for ensuring that + // all callbacks defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length == 0) funcs = _.functions(obj); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(func, args); }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + + // Internal function used to implement `_.throttle` and `_.debounce`. + var limit = function(func, wait, debounce) { + var timeout; + return function() { + var context = this, args = arguments; + var throttler = function() { + timeout = null; + func.apply(context, args); + }; + if (debounce) clearTimeout(timeout); + if (debounce || !timeout) timeout = setTimeout(throttler, wait); + }; + }; + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. + _.throttle = function(func, wait) { + return limit(func, wait, false); + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. + _.debounce = function(func, wait) { + return limit(func, wait, true); + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + return memo = func.apply(this, arguments); + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return function() { + var args = [func].concat(slice.call(arguments)); + return wrapper.apply(this, args); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = slice.call(arguments); + return function() { + var args = slice.call(arguments); + for (var i=funcs.length-1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + return function() { + if (--times < 1) { return func.apply(this, arguments); } + }; + }; + + + // Object Functions + // ---------------- + + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = nativeKeys || function(obj) { + if (obj !== Object(obj)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key; + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + return _.map(obj, _.identity); + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (source[prop] !== void 0) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (obj[prop] == null) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + // Check object identity. + if (a === b) return true; + // Different types? + var atype = typeof(a), btype = typeof(b); + if (atype != btype) return false; + // Basic equality test (watch out for coercions). + if (a == b) return true; + // One is falsy and the other truthy. + if ((!a && b) || (a && !b)) return false; + // Unwrap any wrapped objects. + if (a._chain) a = a._wrapped; + if (b._chain) b = b._wrapped; + // One of them implements an isEqual()? + if (a.isEqual) return a.isEqual(b); + // Check dates' integer values. + if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime(); + // Both are NaN? + if (_.isNaN(a) && _.isNaN(b)) return false; + // Compare regular expressions. + if (_.isRegExp(a) && _.isRegExp(b)) + return a.source === b.source && + a.global === b.global && + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline; + // If a is not an object by this point, we can't handle it. + if (atype !== 'object') return false; + // Check for different array lengths before comparing contents. + if (a.length && (a.length !== b.length)) return false; + // Nothing else worked, deep compare the contents. + var aKeys = _.keys(a), bKeys = _.keys(b); + // Different object sizes? + if (aKeys.length != bKeys.length) return false; + // Recursive comparison of contents. + for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false; + return true; + }; + + // Is a given array or object empty? + _.isEmpty = function(obj) { + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (hasOwnProperty.call(obj, key)) return false; + return true; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType == 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an arguments object? + _.isArguments = function(obj) { + return !!(obj && hasOwnProperty.call(obj, 'callee')); + }; + + // Is a given value a function? + _.isFunction = function(obj) { + return !!(obj && obj.constructor && obj.call && obj.apply); + }; + + // Is a given value a string? + _.isString = function(obj) { + return !!(obj === '' || (obj && obj.charCodeAt && obj.substr)); + }; + + // Is a given value a number? + _.isNumber = function(obj) { + return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed)); + }; + + // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript + // that does not equal itself. + _.isNaN = function(obj) { + return obj !== obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false; + }; + + // Is a given value a date? + _.isDate = function(obj) { + return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear); + }; + + // Is the given value a regular expression? + _.isRegExp = function(obj) { + return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false)); + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; + + // Run a function **n** times. + _.times = function (n, iterator, context) { + for (var i = 0; i < n; i++) iterator.call(context, i); + }; + + // Add your own custom functions to the Underscore object, ensuring that + // they're correctly added to the OOP wrapper as well. + _.mixin = function(obj) { + each(_.functions(obj), function(name){ + addToWrapper(name, _[name] = obj[name]); + }); + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = idCounter++; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(str, data) { + var c = _.templateSettings; + var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + + 'with(obj||{}){__p.push(\'' + + str.replace(/\\/g, '\\\\') + .replace(/'/g, "\\'") + .replace(c.interpolate, function(match, code) { + return "'," + code.replace(/\\'/g, "'") + ",'"; + }) + .replace(c.evaluate || null, function(match, code) { + return "');" + code.replace(/\\'/g, "'") + .replace(/[\r\n\t]/g, ' ') + "__p.push('"; + }) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + + "');}return __p.join('');"; + var func = new Function('obj', tmpl); + return data ? func(data) : func; + }; + + // The OOP Wrapper + // --------------- + + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + var wrapper = function(obj) { this._wrapped = obj; }; + + // Expose `wrapper.prototype` as `_.prototype` + _.prototype = wrapper.prototype; + + // Helper function to continue chaining intermediate results. + var result = function(obj, chain) { + return chain ? _(obj).chain() : obj; + }; + + // A method to easily add functions to the OOP wrapper. + var addToWrapper = function(name, func) { + wrapper.prototype[name] = function() { + var args = slice.call(arguments); + unshift.call(args, this._wrapped); + return result(func.apply(_, args), this._chain); + }; + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + method.apply(this._wrapped, arguments); + return result(this._wrapped, this._chain); + }; + }); + + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + return result(method.apply(this._wrapped, arguments), this._chain); + }; + }); + + // Start chaining a wrapped Underscore object. + wrapper.prototype.chain = function() { + this._chain = true; + return this; + }; + + // Extracts the result from a wrapped and chained object. + wrapper.prototype.value = function() { + return this._wrapped; + }; + +})(); diff --git a/node_modules/underscore/.npmignore b/node_modules/underscore/.npmignore new file mode 100644 index 00000000..f5717584 --- /dev/null +++ b/node_modules/underscore/.npmignore @@ -0,0 +1,4 @@ +test/ +underscore-min.js +Rakefile +docs/ \ No newline at end of file diff --git a/node_modules/underscore/LICENSE b/node_modules/underscore/LICENSE new file mode 100644 index 00000000..58c73b9e --- /dev/null +++ b/node_modules/underscore/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2011 Jeremy Ashkenas, DocumentCloud + +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. \ No newline at end of file diff --git a/node_modules/underscore/README b/node_modules/underscore/README new file mode 100644 index 00000000..408145aa --- /dev/null +++ b/node_modules/underscore/README @@ -0,0 +1,19 @@ + __ + /\ \ __ + __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____ +/\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\ +\ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\ + \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/ + \/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/ + \ \____/ + \/___/ + +Underscore is a utility-belt library for JavaScript that provides +support for the usual functional suspects (each, map, reduce, filter...) +without extending any core JavaScript objects. + +For Docs, License, Tests, and pre-packed downloads, see: +http://documentcloud.github.com/underscore/ + +Many thanks to our contributors: +https://github.com/documentcloud/underscore/contributors diff --git a/node_modules/underscore/index.html b/node_modules/underscore/index.html new file mode 100644 index 00000000..04c878ad --- /dev/null +++ b/node_modules/underscore/index.html @@ -0,0 +1,1560 @@ + + + + + + Underscore.js + + + + +
        + +

        Underscore.js

        + +

        + Underscore is a + utility-belt library for JavaScript that provides a lot of the + functional programming support that you would expect in + Prototype.js + (or Ruby), + but without extending any of the built-in JavaScript objects. It's the + tie to go along with jQuery's tux. +

        + +

        + Underscore provides 60-odd functions that support both the usual + functional suspects: map, select, invoke — + as well as more specialized helpers: function binding, javascript + templating, deep equality testing, and so on. It delegates to built-in + functions, if present, so modern browsers will use the + native implementations of forEach, map, reduce, + filter, every, some and indexOf. +

        + +

        + A complete Test & Benchmark Suite + is included for your perusal. +

        + +

        + You may also read through the annotated source code. +

        + +

        + The project is + hosted on GitHub. + You can report bugs and discuss features on the + issues page, + on Freenode in the #documentcloud channel, + or send tweets to @documentcloud. +

        + +

        + Underscore is an open-source component of DocumentCloud. +

        + +

        Downloads (Right-click, and use "Save As")

        + + + + + + + + + + +
        Development Version (1.1.6)27kb, Uncompressed with Comments
        Production Version (1.1.6)3kb, Minified and Gzipped
        + +

        Table of Contents

        + + Object-Oriented and Functional Styles + +

        + Collections +
        + each, map, + reduce, reduceRight, + detect, select, + reject, all, + any, include, + invoke, pluck, + max, min, + sortBy, sortedIndex, + toArray, size +

        + +

        + Arrays +
        + first, rest, last, + compact, flatten, without, uniq, + intersect, zip, indexOf, + lastIndexOf, range +

        + +

        + Functions +
        + bind, bindAll, + memoize, delay, defer, + throttle, debounce, + once, after, wrap, compose +

        + +

        + Objects +
        + keys, values, + functions, extend, defaults, clone, tap, + isEqual, isEmpty, isElement, + isArray, isArguments, isFunction, isString, + isNumber, isBoolean, isDate, isRegExp + isNaN, isNull, + isUndefined + +

        + +

        + Utility +
        + noConflict, + identity, times, + mixin, uniqueId, + template +

        + +

        + Chaining +
        + chain, value +

        + +
        + +

        Object-Oriented and Functional Styles

        + +

        + You can use Underscore in either an object-oriented or a functional style, + depending on your preference. The following two lines of code are + identical ways to double a list of numbers. +

        + +
        +_.map([1, 2, 3], function(n){ return n * 2; });
        +_([1, 2, 3]).map(function(n){ return n * 2; });
        + +

        + Using the object-oriented style allows you to chain together methods. Calling + chain on a wrapped object will cause all future method calls to + return wrapped objects as well. When you've finished the computation, + use value to retrieve the final value. Here's an example of chaining + together a map/flatten/reduce, in order to get the word count of + every word in a song. +

        + +
        +var lyrics = [
        +  {line : 1, words : "I'm a lumberjack and I'm okay"},
        +  {line : 2, words : "I sleep all night and I work all day"},
        +  {line : 3, words : "He's a lumberjack and he's okay"},
        +  {line : 4, words : "He sleeps all night and he works all day"}
        +];
        +
        +_(lyrics).chain()
        +  .map(function(line) { return line.words.split(' '); })
        +  .flatten()
        +  .reduce(function(counts, word) {
        +    counts[word] = (counts[word] || 0) + 1;
        +    return counts;
        +}, {}).value();
        +
        +=> {lumberjack : 2, all : 4, night : 2 ... }
        + +

        + In addition, the + Array prototype's methods + are proxied through the chained Underscore object, so you can slip a + reverse or a push into your chain, and continue to + modify the array. +

        + +

        Collection Functions (Arrays or Objects)

        + +

        + each_.each(list, iterator, [context]) + Alias: forEach +
        + Iterates over a list of elements, yielding each in turn to an iterator + function. The iterator is bound to the context object, if one is + passed. Each invocation of iterator is called with three arguments: + (element, index, list). If list is a JavaScript object, iterator's + arguments will be (value, key, list). Delegates to the native + forEach function if it exists. +

        +
        +_.each([1, 2, 3], function(num){ alert(num); });
        +=> alerts each number in turn...
        +_.each({one : 1, two : 2, three : 3}, function(num, key){ alert(num); });
        +=> alerts each number in turn...
        + +

        + map_.map(list, iterator, [context]) +
        + Produces a new array of values by mapping each value in list + through a transformation function (iterator). If the native map method + exists, it will be used instead. If list is a JavaScript object, + iterator's arguments will be (value, key, list). +

        +
        +_.map([1, 2, 3], function(num){ return num * 3; });
        +=> [3, 6, 9]
        +_.map({one : 1, two : 2, three : 3}, function(num, key){ return num * 3; });
        +=> [3, 6, 9]
        + +

        + reduce_.reduce(list, iterator, memo, [context]) + Aliases: inject, foldl +
        + Also known as inject and foldl, reduce boils down a + list of values into a single value. Memo is the initial state + of the reduction, and each successive step of it should be returned by + iterator. +

        +
        +var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
        +=> 6
        +
        + +

        + reduceRight_.reduceRight(list, iterator, memo, [context]) + Alias: foldr +
        + The right-associative version of reduce. Delegates to the + JavaScript 1.8 version of reduceRight, if it exists. Foldr + is not as useful in JavaScript as it would be in a language with lazy + evaluation. +

        +
        +var list = [[0, 1], [2, 3], [4, 5]];
        +var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
        +=> [4, 5, 2, 3, 0, 1]
        +
        + +

        + detect_.detect(list, iterator, [context]) +
        + Looks through each value in the list, returning the first one that + passes a truth test (iterator). The function returns as + soon as it finds an acceptable element, and doesn't traverse the + entire list. +

        +
        +var even = _.detect([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
        +=> 2
        +
        + +

        + select_.select(list, iterator, [context]) + Alias: filter +
        + Looks through each value in the list, returning an array of all + the values that pass a truth test (iterator). Delegates to the + native filter method, if it exists. +

        +
        +var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
        +=> [2, 4, 6]
        +
        + +

        + reject_.reject(list, iterator, [context]) +
        + Returns the values in list without the elements that the truth + test (iterator) passes. The opposite of select. +

        +
        +var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
        +=> [1, 3, 5]
        +
        + +

        + all_.all(list, [iterator], [context]) + Alias: every +
        + Returns true if all of the values in the list pass the iterator + truth test. If an iterator is not provided, the truthy value of + the element will be used instead. Delegates to the native method every, if + present. +

        +
        +_.all([true, 1, null, 'yes']);
        +=> false
        +
        + +

        + any_.any(list, [iterator], [context]) + Alias: some +
        + Returns true if any of the values in the list pass the + iterator truth test. Short-circuits and stops traversing the list + if a true element is found. Delegates to the native method some, + if present. +

        +
        +_.any([null, 0, 'yes', false]);
        +=> true
        +
        + +

        + include_.include(list, value) + Alias: contains +
        + Returns true if the value is present in the list, using + === to test equality. Uses indexOf internally, if list + is an Array. +

        +
        +_.include([1, 2, 3], 3);
        +=> true
        +
        + +

        + invoke_.invoke(list, methodName, [*arguments]) +
        + Calls the method named by methodName on each value in the list. + Any extra arguments passed to invoke will be forwarded on to the + method invocation. +

        +
        +_.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
        +=> [[1, 5, 7], [1, 2, 3]]
        +
        + +

        + pluck_.pluck(list, propertyName) +
        + An convenient version of what is perhaps the most common use-case for + map: extracting a list of property values. +

        +
        +var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}];
        +_.pluck(stooges, 'name');
        +=> ["moe", "larry", "curly"]
        +
        + +

        + max_.max(list, [iterator], [context]) +
        + Returns the maximum value in list. If iterator is passed, + it will be used on each value to generate the criterion by which the + value is ranked. +

        +
        +var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}];
        +_.max(stooges, function(stooge){ return stooge.age; });
        +=> {name : 'curly', age : 60};
        +
        + +

        + min_.min(list, [iterator], [context]) +
        + Returns the minimum value in list. If iterator is passed, + it will be used on each value to generate the criterion by which the + value is ranked. +

        +
        +var numbers = [10, 5, 100, 2, 1000];
        +_.min(numbers);
        +=> 2
        +
        + +

        + sortBy_.sortBy(list, iterator, [context]) +
        + Returns a sorted list, ranked by the results of running each + value through iterator. +

        +
        +_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); });
        +=> [5, 4, 6, 3, 1, 2]
        +
        + +

        + sortedIndex_.sortedIndex(list, value, [iterator]) +
        + Uses a binary search to determine the index at which the value + should be inserted into the list in order to maintain the list's + sorted order. If an iterator is passed, it will be used to compute + the sort ranking of each value. +

        +
        +_.sortedIndex([10, 20, 30, 40, 50], 35);
        +=> 3
        +
        + +

        + toArray_.toArray(list) +
        + Converts the list (anything that can be iterated over), into a + real Array. Useful for transmuting the arguments object. +

        +
        +(function(){ return _.toArray(arguments).slice(0); })(1, 2, 3);
        +=> [1, 2, 3]
        +
        + +

        + size_.size(list) +
        + Return the number of values in the list. +

        +
        +_.size({one : 1, two : 2, three : 3});
        +=> 3
        +
        + +

        Array Functions

        + +

        + Note: All array functions will also work on the arguments object. +

        + +

        + first_.first(array, [n]) + Alias: head +
        + Returns the first element of an array. Passing n will + return the first n elements of the array. +

        +
        +_.first([5, 4, 3, 2, 1]);
        +=> 5
        +
        + +

        + rest_.rest(array, [index]) + Alias: tail +
        + Returns the rest of the elements in an array. Pass an index + to return the values of the array from that index onward. +

        +
        +_.rest([5, 4, 3, 2, 1]);
        +=> [4, 3, 2, 1]
        +
        + +

        + last_.last(array) +
        + Returns the last element of an array. +

        +
        +_.last([5, 4, 3, 2, 1]);
        +=> 1
        +
        + +

        + compact_.compact(array) +
        + Returns a copy of the array with all falsy values removed. + In JavaScript, false, null, 0, "", + undefined and NaN are all falsy. +

        +
        +_.compact([0, 1, false, 2, '', 3]);
        +=> [1, 2, 3]
        +
        + +

        + flatten_.flatten(array) +
        + Flattens a nested array (the nesting can be to any depth). +

        +
        +_.flatten([1, [2], [3, [[[4]]]]]);
        +=> [1, 2, 3, 4];
        +
        + +

        + without_.without(array, [*values]) +
        + Returns a copy of the array with all instances of the values + removed. === is used for the equality test. +

        +
        +_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
        +=> [2, 3, 4]
        +
        + +

        + uniq_.uniq(array, [isSorted]) + Alias: unique +
        + Produces a duplicate-free version of the array, using === to test + object equality. If you know in advance that the array is sorted, + passing true for isSorted will run a much faster algorithm. +

        +
        +_.uniq([1, 2, 1, 3, 1, 4]);
        +=> [1, 2, 3, 4]
        +
        + +

        + intersect_.intersect(*arrays) +
        + Computes the list of values that are the intersection of all the arrays. + Each value in the result is present in each of the arrays. +

        +
        +_.intersect([1, 2, 3], [101, 2, 1, 10], [2, 1]);
        +=> [1, 2]
        +
        + +

        + zip_.zip(*arrays) +
        + Merges together the values of each of the arrays with the + values at the corresponding position. Useful when you have separate + data sources that are coordinated through matching array indexes. + If you're working with a matrix of nested arrays, zip.apply + can transpose the matrix in a similar fashion. +

        +
        +_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
        +=> [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]
        +
        + +

        + indexOf_.indexOf(array, value, [isSorted]) +
        + Returns the index at which value can be found in the array, + or -1 if value is not present in the array. Uses the native + indexOf function unless it's missing. If you're working with a + large array, and you know that the array is already sorted, pass true + for isSorted to use a faster binary search. +

        +
        +_.indexOf([1, 2, 3], 2);
        +=> 1
        +
        + +

        + lastIndexOf_.lastIndexOf(array, value) +
        + Returns the index of the last occurrence of value in the array, + or -1 if value is not present. Uses the native lastIndexOf + function if possible. +

        +
        +_.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
        +=> 4
        +
        + +

        + range_.range([start], stop, [step]) +
        + A function to create flexibly-numbered lists of integers, handy for + each and map loops. start, if omitted, defaults + to 0; step defaults to 1. Returns a list of integers + from start to stop, incremented (or decremented) by step, + exclusive. +

        +
        +_.range(10);
        +=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        +_.range(1, 11);
        +=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        +_.range(0, 30, 5);
        +=> [0, 5, 10, 15, 20, 25]
        +_.range(0, -10, -1);
        +=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
        +_.range(0);
        +=> []
        +
        + +

        Function (uh, ahem) Functions

        + +

        + bind_.bind(function, object, [*arguments]) +
        + Bind a function to an object, meaning that whenever + the function is called, the value of this will be the object. + Optionally, bind arguments to the function to pre-fill them, + also known as currying. +

        +
        +var func = function(greeting){ return greeting + ': ' + this.name };
        +func = _.bind(func, {name : 'moe'}, 'hi');
        +func();
        +=> 'hi: moe'
        +
        + +

        + bindAll_.bindAll(object, [*methodNames]) +
        + Binds a number of methods on the object, specified by + methodNames, to be run in the context of that object whenever they + are invoked. Very handy for binding functions that are going to be used + as event handlers, which would otherwise be invoked with a fairly useless + this. If no methodNames are provided, all of the object's + function properties will be bound to it. +

        +
        +var buttonView = {
        +  label   : 'underscore',
        +  onClick : function(){ alert('clicked: ' + this.label); },
        +  onHover : function(){ console.log('hovering: ' + this.label); }
        +};
        +_.bindAll(buttonView);
        +jQuery('#underscore_button').bind('click', buttonView.onClick);
        +=> When the button is clicked, this.label will have the correct value...
        +
        + +

        + memoize_.memoize(function, [hashFunction]) +
        + Memoizes a given function by caching the computed result. Useful + for speeding up slow-running computations. If passed an optional + hashFunction, it will be used to compute the hash key for storing + the result, based on the arguments to the original function. The default + hashFunction just uses the first argument to the memoized function + as the key. +

        +
        +var fibonacci = function(n) {
        +  return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
        +};
        +var fastFibonacci = _.memoize(fibonacci);
        +
        + +

        + delay_.delay(function, wait, [*arguments]) +
        + Much like setTimeout, invokes function after wait + milliseconds. If you pass the optional arguments, they will be + forwarded on to the function when it is invoked. +

        +
        +var log = _.bind(console.log, console);
        +_.delay(log, 1000, 'logged later');
        +=> 'logged later' // Appears after one second.
        +
        + +

        + defer_.defer(function) +
        + Defers invoking the function until the current call stack has cleared, + similar to using setTimeout with a delay of 0. Useful for performing + expensive computations or HTML rendering in chunks without blocking the UI thread + from updating. +

        +
        +_.defer(function(){ alert('deferred'); });
        +// Returns from the function before the alert runs.
        +
        + +

        + throttle_.throttle(function, wait) +
        + Returns a throttled version of the function, that, when invoked repeatedly, + will only actually call the wrapped function at most once per every wait + milliseconds. Useful for rate-limiting events that occur faster than you + can keep up with. +

        +
        +var throttled = _.throttle(updatePosition, 100);
        +$(window).scroll(throttled);
        +
        + +

        + debounce_.debounce(function, wait) +
        + Repeated calls to a debounced function will postpone it's execution + until after wait milliseconds have elapsed. Useful for implementing + behavior that should only happen after the input has stopped arriving. + For example: rendering a preview of a Markdown comment, recalculating a + layout after the window has stopped being resized... +

        +
        +var lazyLayout = _.debounce(calculateLayout, 300);
        +$(window).resize(lazyLayout);
        +
        + +

        + once_.once(function) +
        + Creates a version of the function that can only be called one time. + Repeated calls to the modified function will have no effect, returning + the value from the original call. Useful for initialization functions, + instead of having to set a boolean flag and then check it later. +

        +
        +var initialize = _.once(createApplication);
        +initialize();
        +initialize();
        +// Application is only created once.
        +
        + +

        + after_.after(count, function) +
        + Creates a version of the function that will only be run after first + being called count times. Useful for grouping asynchronous responses, + where you want to be sure that all the async calls have finished, before + proceeding. +

        +
        +var renderNotes = _.after(notes.length, render);
        +_.each(notes, function(note) {
        +  note.asyncSave({success: renderNotes}); 
        +});
        +// renderNotes is run once, after all notes have saved.
        +
        + +

        + wrap_.wrap(function, wrapper) +
        + Wraps the first function inside of the wrapper function, + passing it as the first argument. This allows the wrapper to + execute code before and after the function runs, adjust the arguments, + and execute it conditionally. +

        +
        +var hello = function(name) { return "hello: " + name; };
        +hello = _.wrap(hello, function(func) {
        +  return "before, " + func("moe") + ", after";
        +});
        +hello();
        +=> 'before, hello: moe, after'
        +
        + +

        + compose_.compose(*functions) +
        + Returns the composition of a list of functions, where each function + consumes the return value of the function that follows. In math terms, + composing the functions f(), g(), and h() produces + f(g(h())). +

        +
        +var greet    = function(name){ return "hi: " + name; };
        +var exclaim  = function(statement){ return statement + "!"; };
        +var welcome = _.compose(exclaim, greet);
        +welcome('moe');
        +=> 'hi: moe!'
        +
        + +

        Object Functions

        + +

        + keys_.keys(object) +
        + Retrieve all the names of the object's properties. +

        +
        +_.keys({one : 1, two : 2, three : 3});
        +=> ["one", "two", "three"]
        +
        + +

        + values_.values(object) +
        + Return all of the values of the object's properties. +

        +
        +_.values({one : 1, two : 2, three : 3});
        +=> [1, 2, 3]
        +
        + +

        + functions_.functions(object) + Alias: methods +
        + Returns a sorted list of the names of every method in an object — + that is to say, the name of every function property of the object. +

        +
        +_.functions(_);
        +=> ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ...
        +
        + +

        + extend_.extend(destination, *sources) +
        + Copy all of the properties in the source objects over to the + destination object. It's in-order, to the last source will override + properties of the same name in previous arguments. +

        +
        +_.extend({name : 'moe'}, {age : 50});
        +=> {name : 'moe', age : 50}
        +
        + +

        + defaults_.defaults(object, *defaults) +
        + Fill in missing properties in object with default values from the + defaults objects. As soon as the property is filled, further defaults + will have no effect. +

        +
        +var iceCream = {flavor : "chocolate"};
        +_.defaults(iceCream, {flavor : "vanilla", sprinkles : "lots"});
        +=> {flavor : "chocolate", sprinkles : "lots"}
        +
        + +

        + clone_.clone(object) +
        + Create a shallow-copied clone of the object. Any nested objects + or arrays will be copied by reference, not duplicated. +

        +
        +_.clone({name : 'moe'});
        +=> {name : 'moe'};
        +
        + +

        + tap_.tap(object, interceptor) +
        + Invokes interceptor with the object, and then returns object. + The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. +

        +
        +_([1,2,3,200]).chain().
        +  select(function(num) { return num % 2 == 0; }).
        +  tap(console.log).
        +  map(function(num) { return num * num }).
        +  value();
        +=> [2, 200]
        +=> [4, 40000]
        +
        + +

        + isEqual_.isEqual(object, other) +
        + Performs an optimized deep comparison between the two objects, to determine + if they should be considered equal. +

        +
        +var moe   = {name : 'moe', luckyNumbers : [13, 27, 34]};
        +var clone = {name : 'moe', luckyNumbers : [13, 27, 34]};
        +moe == clone;
        +=> false
        +_.isEqual(moe, clone);
        +=> true
        +
        + +

        + isEmpty_.isEmpty(object) +
        + Returns true if object contains no values. +

        +
        +_.isEmpty([1, 2, 3]);
        +=> false
        +_.isEmpty({});
        +=> true
        +
        + +

        + isElement_.isElement(object) +
        + Returns true if object is a DOM element. +

        +
        +_.isElement(jQuery('body')[0]);
        +=> true
        +
        + +

        + isArray_.isArray(object) +
        + Returns true if object is an Array. +

        +
        +(function(){ return _.isArray(arguments); })();
        +=> false
        +_.isArray([1,2,3]);
        +=> true
        +
        + +

        + isArguments_.isArguments(object) +
        + Returns true if object is an Arguments object. +

        +
        +(function(){ return _.isArguments(arguments); })(1, 2, 3);
        +=> true
        +_.isArguments([1,2,3]);
        +=> false
        +
        + +

        + isFunction_.isFunction(object) +
        + Returns true if object is a Function. +

        +
        +_.isFunction(alert);
        +=> true
        +
        + +

        + isString_.isString(object) +
        + Returns true if object is a String. +

        +
        +_.isString("moe");
        +=> true
        +
        + +

        + isNumber_.isNumber(object) +
        + Returns true if object is a Number. +

        +
        +_.isNumber(8.4 * 5);
        +=> true
        +
        + +

        + isBoolean_.isBoolean(object) +
        + Returns true if object is either true or false. +

        +
        +_.isBoolean(null);
        +=> false
        +
        + +

        + isDate_.isDate(object) +
        + Returns true if object is a Date. +

        +
        +_.isDate(new Date());
        +=> true
        +
        + +

        + isRegExp_.isRegExp(object) +
        + Returns true if object is a RegExp. +

        +
        +_.isRegExp(/moe/);
        +=> true
        +
        + +

        + isNaN_.isNaN(object) +
        + Returns true if object is NaN.
        Note: this is not + the same as the native isNaN function, which will also return + true if the variable is undefined. +

        +
        +_.isNaN(NaN);
        +=> true
        +isNaN(undefined);
        +=> true
        +_.isNaN(undefined);
        +=> false
        +
        + +

        + isNull_.isNull(object) +
        + Returns true if the value of object is null. +

        +
        +_.isNull(null);
        +=> true
        +_.isNull(undefined);
        +=> false
        +
        + +

        + isUndefined_.isUndefined(variable) +
        + Returns true if variable is undefined. +

        +
        +_.isUndefined(window.missingVariable);
        +=> true
        +
        + +

        Utility Functions

        + +

        + noConflict_.noConflict() +
        + Give control of the "_" variable back to its previous owner. Returns + a reference to the Underscore object. +

        +
        +var underscore = _.noConflict();
        + +

        + identity_.identity(value) +
        + Returns the same value that is used as the argument. In math: + f(x) = x
        + This function looks useless, but is used throughout Underscore as + a default iterator. +

        +
        +var moe = {name : 'moe'};
        +moe === _.identity(moe);
        +=> true
        + +

        + times_.times(n, iterator) +
        + Invokes the given iterator function n times. +

        +
        +_(3).times(function(){ genie.grantWish(); });
        + +

        + mixin_.mixin(object) +
        + Allows you to extend Underscore with your own utility functions. Pass + a hash of {name: function} definitions to have your functions + added to the Underscore object, as well as the OOP wrapper. +

        +
        +_.mixin({
        +  capitalize : function(string) {
        +    return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
        +  }
        +});
        +_("fabio").capitalize();
        +=> "Fabio"
        +
        + +

        + uniqueId_.uniqueId([prefix]) +
        + Generate a globally-unique id for client-side models or DOM elements + that need one. If prefix is passed, the id will be appended to it. +

        +
        +_.uniqueId('contact_');
        +=> 'contact_104'
        + +

        + template_.template(templateString, [context]) +
        + Compiles JavaScript templates into functions that can be evaluated + for rendering. Useful for rendering complicated bits of HTML from JSON + data sources. Template functions can both interpolate variables, using
        + <%= … %>, as well as execute arbitrary JavaScript code, with + <% … %>. When you evaluate a template function, pass in a + context object that has properties corresponding to the template's free + variables. If you're writing a one-off, you can pass the context + object as the second parameter to template in order to render + immediately instead of returning a template function. +

        +
        +var compiled = _.template("hello: <%= name %>");
        +compiled({name : 'moe'});
        +=> "hello: moe"
        +
        +var list = "<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>";
        +_.template(list, {people : ['moe', 'curly', 'larry']});
        +=> "<li>moe</li><li>curly</li><li>larry</li>"
        + +

        + You can also use print from within JavaScript code. This is + sometimes more convenient than using <%= ... %>. +

        + +
        +var compiled = _.template("<% print('Hello ' + epithet); %>");
        +compiled({epithet: "stooge"});
        +=> "Hello stooge."
        + +

        + If ERB-style delimiters aren't your cup of tea, you can change Underscore's + template settings to use different symbols to set off interpolated code. + Define an interpolate regex, and an (optional) evaluate regex + to match expressions that should be inserted and evaluated, respectively. + If no evaluate regex is provided, your templates will only be + capable of interpolating values. + For example, to perform + Mustache.js + style templating: +

        + +
        +_.templateSettings = {
        +  interpolate : /\{\{(.+?)\}\}/g
        +};
        +
        +var template = _.template("Hello {{ name }}!");
        +template({name : "Mustache"});
        +=> "Hello Mustache!"
        + +

        Chaining

        + +

        + chain_(obj).chain() +
        + Returns a wrapped object. Calling methods on this object will continue + to return wrapped objects until value is used. ( + A more realistic example.) +

        +
        +var stooges = [{name : 'curly', age : 25}, {name : 'moe', age : 21}, {name : 'larry', age : 23}];
        +var youngest = _(stooges).chain()
        +  .sortBy(function(stooge){ return stooge.age; })
        +  .map(function(stooge){ return stooge.name + ' is ' + stooge.age; })
        +  .first()
        +  .value();
        +=> "moe is 21"
        +
        + +

        + value_(obj).value() +
        + Extracts the value of a wrapped object. +

        +
        +_([1, 2, 3]).value();
        +=> [1, 2, 3]
        +
        + +

        Duck Typing

        + +

        + The isType (isArray, isFunction, isString ...) family of type-checking + functions use property detection to do their work, which, although + orders of magnitude faster than the alternative, isn't entirely safe when dealing + with objects that are used as hashes, where arbitrary strings are being + set for the keys. It's entirely possible for an object to masquerade as + another type, if you're setting properties with names like "concat" and + "charCodeAt". So be aware. +

        + + +

        Links & Suggested Reading

        + +

        + Underscore.lua, + a Lua port of the functions that are applicable in both languages. + Includes OOP-wrapping and chaining. + The source is + available on GitHub. +

        + +

        + Underscore.string, + an Underscore extension that adds functions for string-manipulation: + trim, startsWith, contains, capitalize, + reverse, sprintf, and more. +

        + +

        + Ruby's Enumerable module. +

        + +

        + Prototype.js, which provides + JavaScript with collection functions in the manner closest to Ruby's Enumerable. +

        + +

        + Oliver Steele's + Functional JavaScript, + which includes comprehensive higher-order function support as well as string lambdas. +

        + +

        + Python's itertools. +

        + +

        Change Log

        + +

        + 1.1.6April 18, 2011
        + Added _.after, which will return a function that only runs after + first being called a specified number of times. + _.invoke can now take a direct function reference. + _.every now requires an iterator function to be passed, which + mirrors the ECMA5 API. + _.extend no longer copies keys when the value is undefined. + _.bind now errors when trying to bind an undefined value. +

        + +

        + 1.1.5Mar 20, 2011
        + Added an _.defaults function, for use merging together JS objects + representing default options. + Added an _.once function, for manufacturing functions that should + only ever execute a single time. + _.bind now delegates to the native ECMAScript 5 version, + where available. + _.keys now throws an error when used on non-Object values, as in + ECMAScript 5. + Fixed a bug with _.keys when used over sparse arrays. +

        + +

        + 1.1.4Jan 9, 2011
        + Improved compliance with ES5's Array methods when passing null + as a value. _.wrap now correctly sets this for the + wrapped function. _.indexOf now takes an optional flag for + finding the insertion index in an array that is guaranteed to already + be sorted. Avoiding the use of .callee, to allow _.isArray + to work properly in ES5's strict mode. +

        + +

        + 1.1.3Dec 1, 2010
        + In CommonJS, Underscore may now be required with just:
        + var _ = require("underscore"). + Added _.throttle and _.debounce functions. + Removed _.breakLoop, in favor of an ECMA5-style un-break-able + each implementation — this removes the try/catch, and you'll now have + better stack traces for exceptions that are thrown within an Underscore iterator. + Improved the isType family of functions for better interoperability + with Internet Explorer host objects. + _.template now correctly escapes backslashes in templates. + Improved _.reduce compatibility with the ECMA5 version: + if you don't pass an initial value, the first item in the collection is used. + _.each no longer returns the iterated collection, for improved + consistency with ES5's forEach. +

        + +

        + 1.1.2
        + Fixed _.contains, which was mistakenly pointing at + _.intersect instead of _.include, like it should + have been. Added _.unique as an alias for _.uniq. +

        + +

        + 1.1.1
        + Improved the speed of _.template, and its handling of multiline + interpolations. Ryan Tenney contributed optimizations to many Underscore + functions. An annotated version of the source code is now available. +

        + +

        + 1.1.0
        + The method signature of _.reduce has been changed to match + the ECMAScript 5 signature, instead of the Ruby/Prototype.js version. + This is a backwards-incompatible change. _.template may now be + called with no arguments, and preserves whitespace. _.contains + is a new alias for _.include. +

        + +

        + 1.0.4
        + Andri Möll contributed the _.memoize + function, which can be used to speed up expensive repeated computations + by caching the results. +

        + +

        + 1.0.3
        + Patch that makes _.isEqual return false if any property + of the compared object has a NaN value. Technically the correct + thing to do, but of questionable semantics. Watch out for NaN comparisons. +

        + +

        + 1.0.2
        + Fixes _.isArguments in recent versions of Opera, which have + arguments objects as real Arrays. +

        + +

        + 1.0.1
        + Bugfix for _.isEqual, when comparing two objects with the same + number of undefined keys, but with different names. +

        + +

        + 1.0.0
        + Things have been stable for many months now, so Underscore is now + considered to be out of beta, at 1.0. Improvements since 0.6 + include _.isBoolean, and the ability to have _.extend + take multiple source objects. +

        + +

        + 0.6.0
        + Major release. Incorporates a number of + Mile Frawley's refactors for + safer duck-typing on collection functions, and cleaner internals. A new + _.mixin method that allows you to extend Underscore with utility + functions of your own. Added _.times, which works the same as in + Ruby or Prototype.js. Native support for ECMAScript 5's Array.isArray, + and Object.keys. +

        + +

        + 0.5.8
        + Fixed Underscore's collection functions to work on + NodeLists and + HTMLCollections + once more, thanks to + Justin Tulloss. +

        + +

        + 0.5.7
        + A safer implementation of _.isArguments, and a + faster _.isNumber,
        thanks to + Jed Schmidt. +

        + +

        + 0.5.6
        + Customizable delimiters for _.template, contributed by + Noah Sloan. +

        + +

        + 0.5.5
        + Fix for a bug in MobileSafari's OOP-wrapper, with the arguments object. +

        + +

        + 0.5.4
        + Fix for multiple single quotes within a template string for + _.template. See: + Rick Strahl's blog post. +

        + +

        + 0.5.2
        + New implementations of isArray, isDate, isFunction, + isNumber, isRegExp, and isString, thanks to + a suggestion from + Robert Kieffer. + Instead of doing Object#toString + comparisons, they now check for expected properties, which is less safe, + but more than an order of magnitude faster. Most other Underscore + functions saw minor speed improvements as a result. + Evgeniy Dolzhenko + contributed _.tap, + similar to Ruby 1.9's, + which is handy for injecting side effects (like logging) into chained calls. +

        + +

        + 0.5.1
        + Added an _.isArguments function. Lots of little safety checks + and optimizations contributed by + Noah Sloan and + Andri Möll. +

        + +

        + 0.5.0
        + [API Changes] _.bindAll now takes the context object as + its first parameter. If no method names are passed, all of the context + object's methods are bound to it, enabling chaining and easier binding. + _.functions now takes a single argument and returns the names + of its Function properties. Calling _.functions(_) will get you + the previous behavior. + Added _.isRegExp so that isEqual can now test for RegExp equality. + All of the "is" functions have been shrunk down into a single definition. + Karl Guertin contributed patches. +

        + +

        + 0.4.7
        + Added isDate, isNaN, and isNull, for completeness. + Optimizations for isEqual when checking equality between Arrays + or Dates. _.keys is now 25%–2X faster (depending on your + browser) which speeds up the functions that rely on it, such as _.each. +

        + +

        + 0.4.6
        + Added the range function, a port of the + Python + function of the same name, for generating flexibly-numbered lists + of integers. Original patch contributed by + Kirill Ishanov. +

        + +

        + 0.4.5
        + Added rest for Arrays and arguments objects, and aliased + first as head, and rest as tail, + thanks to Luke Sutton's patches. + Added tests ensuring that all Underscore Array functions also work on + arguments objects. +

        + +

        + 0.4.4
        + Added isString, and isNumber, for consistency. Fixed + _.isEqual(NaN, NaN) to return true (which is debatable). +

        + +

        + 0.4.3
        + Started using the native StopIteration object in browsers that support it. + Fixed Underscore setup for CommonJS environments. +

        + +

        + 0.4.2
        + Renamed the unwrapping function to value, for clarity. +

        + +

        + 0.4.1
        + Chained Underscore objects now support the Array prototype methods, so + that you can perform the full range of operations on a wrapped array + without having to break your chain. Added a breakLoop method + to break in the middle of any Underscore iteration. Added an + isEmpty function that works on arrays and objects. +

        + +

        + 0.4.0
        + All Underscore functions can now be called in an object-oriented style, + like so: _([1, 2, 3]).map(...);. Original patch provided by + Marc-André Cournoyer. + Wrapped objects can be chained through multiple + method invocations. A functions method + was added, providing a sorted list of all the functions in Underscore. +

        + +

        + 0.3.3
        + Added the JavaScript 1.8 function reduceRight. Aliased it + as foldr, and aliased reduce as foldl. +

        + +

        + 0.3.2
        + Now runs on stock Rhino + interpreters with: load("underscore.js"). + Added identity as a utility function. +

        + +

        + 0.3.1
        + All iterators are now passed in the original collection as their third + argument, the same as JavaScript 1.6's forEach. Iterating over + objects is now called with (value, key, collection), for details + see _.each. +

        + +

        + 0.3.0
        + Added Dmitry Baranovskiy's + comprehensive optimizations, merged in + Kris Kowal's patches to make Underscore + CommonJS and + Narwhal compliant. +

        + +

        + 0.2.0
        + Added compose and lastIndexOf, renamed inject to + reduce, added aliases for inject, filter, + every, some, and forEach. +

        + +

        + 0.1.1
        + Added noConflict, so that the "Underscore" object can be assigned to + other variables. +

        + +

        + 0.1.0
        + Initial release of Underscore.js. +

        + +

        + + A DocumentCloud Project + +

        + +
        + +
        + + + + + + diff --git a/node_modules/underscore/index.js b/node_modules/underscore/index.js new file mode 100644 index 00000000..2cf0ca5b --- /dev/null +++ b/node_modules/underscore/index.js @@ -0,0 +1 @@ +module.exports = require('./underscore'); diff --git a/node_modules/underscore/package.json b/node_modules/underscore/package.json new file mode 100644 index 00000000..86c91859 --- /dev/null +++ b/node_modules/underscore/package.json @@ -0,0 +1,12 @@ +{ + "name" : "underscore", + "description" : "JavaScript's functional programming helper library.", + "homepage" : "http://documentcloud.github.com/underscore/", + "keywords" : ["util", "functional", "server", "client", "browser"], + "author" : "Jeremy Ashkenas ", + "contributors" : [], + "dependencies" : [], + "repository" : {"type": "git", "url": "git://github.com/documentcloud/underscore.git"}, + "main" : "underscore.js", + "version" : "1.1.6" +} diff --git a/node_modules/underscore/underscore.js b/node_modules/underscore/underscore.js new file mode 100644 index 00000000..eaba008c --- /dev/null +++ b/node_modules/underscore/underscore.js @@ -0,0 +1,807 @@ +// Underscore.js 1.1.6 +// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `global` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Establish the object that gets returned to break out of a loop iteration. + var breaker = {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var slice = ArrayProto.slice, + unshift = ArrayProto.unshift, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { return new wrapper(obj); }; + + // Export the Underscore object for **CommonJS**, with backwards-compatibility + // for the old `require()` API. If we're not in CommonJS, add `_` to the + // global object. + if (typeof module !== 'undefined' && module.exports) { + module.exports = _; + _._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.1.6'; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles objects implementing `forEach`, arrays, and raw objects. + // Delegates to **ECMAScript 5**'s native `forEach` if available. + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (_.isNumber(obj.length)) { + for (var i = 0, l = obj.length; i < l; i++) { + if (iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + for (var key in obj) { + if (hasOwnProperty.call(obj, key)) { + if (iterator.call(context, obj[key], key, obj) === breaker) return; + } + } + } + }; + + // Return the results of applying the iterator to each element. + // Delegates to **ECMAScript 5**'s native `map` if available. + _.map = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results[results.length] = iterator.call(context, value, index, list); + }); + return results; + }; + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = memo !== void 0; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial && index === 0) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError("Reduce of empty array with no initial value"); + return memo; + }; + + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse(); + return _.reduce(reversed, iterator, memo, context); + }; + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, iterator, context) { + var result; + any(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); + each(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + each(obj, function(value, index, list) { + if (!iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, iterator, context) { + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); + each(obj, function(value, index, list) { + if (!(result = result && iterator.call(context, value, index, list))) return breaker; + }); + return result; + }; + + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); + each(obj, function(value, index, list) { + if (result = iterator.call(context, value, index, list)) return breaker; + }); + return result; + }; + + // Determine if a given value is included in the array or object using `===`. + // Aliased as `contains`. + _.include = _.contains = function(obj, target) { + var found = false; + if (obj == null) return found; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + any(obj, function(value) { + if (found = value === target) return true; + }); + return found; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + return _.map(obj, function(value) { + return (method.call ? method || value : value[method]).apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, function(value){ return value[key]; }); + }; + + // Return the maximum element or (element-based computation). + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); + var result = {computed : -Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed >= result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); + var result = {computed : Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed < result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, iterator, context) { + return _.pluck(_.map(obj, function(value, index, list) { + return { + value : value, + criteria : iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }), 'value'); + }; + + // Use a comparator function to figure out at what index an object should + // be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator) { + iterator || (iterator = _.identity); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >> 1; + iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; + } + return low; + }; + + // Safely convert anything iterable into a real, live array. + _.toArray = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) return iterable.toArray(); + if (_.isArray(iterable)) return iterable; + if (_.isArguments(iterable)) return slice.call(iterable); + return _.values(iterable); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + return _.toArray(obj).length; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head`. The **guard** check allows it to work + // with `_.map`. + _.first = _.head = function(array, n, guard) { + return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; + }; + + // Returns everything but the first entry of the array. Aliased as `tail`. + // Especially useful on the arguments object. Passing an **index** will return + // the rest of the values in the array from that index onward. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = function(array, index, guard) { + return slice.call(array, (index == null) || guard ? 1 : index); + }; + + // Get the last element of an array. + _.last = function(array) { + return array[array.length - 1]; + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, function(value){ return !!value; }); + }; + + // Return a completely flattened version of an array. + _.flatten = function(array) { + return _.reduce(array, function(memo, value) { + if (_.isArray(value)) return memo.concat(_.flatten(value)); + memo[memo.length] = value; + return memo; + }, []); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + var values = slice.call(arguments, 1); + return _.filter(array, function(value){ return !_.include(values, value); }); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted) { + return _.reduce(array, function(memo, el, i) { + if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el; + return memo; + }, []); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersect = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.indexOf(other, item) >= 0; + }); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var args = slice.call(arguments); + var length = _.max(_.pluck(args, 'length')); + var results = new Array(length); + for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); + return results; + }; + + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i, l; + if (isSorted) { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); + for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i; + return -1; + }; + + + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item) { + if (array == null) return -1; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); + var i = array.length; + while (i--) if (array[i] === item) return i; + return -1; + }; + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var len = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(len); + + while(idx < len) { + range[idx++] = start; + start += step; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Binding with arguments is also known as `curry`. + // Delegates to **ECMAScript 5**'s native `Function.bind` if available. + // We check for `func.bind` first, to fail fast when `func` is undefined. + _.bind = function(func, obj) { + if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + var args = slice.call(arguments, 2); + return function() { + return func.apply(obj, args.concat(slice.call(arguments))); + }; + }; + + // Bind all of an object's methods to that object. Useful for ensuring that + // all callbacks defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length == 0) funcs = _.functions(obj); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(func, args); }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + + // Internal function used to implement `_.throttle` and `_.debounce`. + var limit = function(func, wait, debounce) { + var timeout; + return function() { + var context = this, args = arguments; + var throttler = function() { + timeout = null; + func.apply(context, args); + }; + if (debounce) clearTimeout(timeout); + if (debounce || !timeout) timeout = setTimeout(throttler, wait); + }; + }; + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. + _.throttle = function(func, wait) { + return limit(func, wait, false); + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. + _.debounce = function(func, wait) { + return limit(func, wait, true); + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + return memo = func.apply(this, arguments); + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return function() { + var args = [func].concat(slice.call(arguments)); + return wrapper.apply(this, args); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = slice.call(arguments); + return function() { + var args = slice.call(arguments); + for (var i=funcs.length-1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + return function() { + if (--times < 1) { return func.apply(this, arguments); } + }; + }; + + + // Object Functions + // ---------------- + + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = nativeKeys || function(obj) { + if (obj !== Object(obj)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key; + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + return _.map(obj, _.identity); + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (source[prop] !== void 0) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (obj[prop] == null) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + // Check object identity. + if (a === b) return true; + // Different types? + var atype = typeof(a), btype = typeof(b); + if (atype != btype) return false; + // Basic equality test (watch out for coercions). + if (a == b) return true; + // One is falsy and the other truthy. + if ((!a && b) || (a && !b)) return false; + // Unwrap any wrapped objects. + if (a._chain) a = a._wrapped; + if (b._chain) b = b._wrapped; + // One of them implements an isEqual()? + if (a.isEqual) return a.isEqual(b); + // Check dates' integer values. + if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime(); + // Both are NaN? + if (_.isNaN(a) && _.isNaN(b)) return false; + // Compare regular expressions. + if (_.isRegExp(a) && _.isRegExp(b)) + return a.source === b.source && + a.global === b.global && + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline; + // If a is not an object by this point, we can't handle it. + if (atype !== 'object') return false; + // Check for different array lengths before comparing contents. + if (a.length && (a.length !== b.length)) return false; + // Nothing else worked, deep compare the contents. + var aKeys = _.keys(a), bKeys = _.keys(b); + // Different object sizes? + if (aKeys.length != bKeys.length) return false; + // Recursive comparison of contents. + for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false; + return true; + }; + + // Is a given array or object empty? + _.isEmpty = function(obj) { + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (hasOwnProperty.call(obj, key)) return false; + return true; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType == 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an arguments object? + _.isArguments = function(obj) { + return !!(obj && hasOwnProperty.call(obj, 'callee')); + }; + + // Is a given value a function? + _.isFunction = function(obj) { + return !!(obj && obj.constructor && obj.call && obj.apply); + }; + + // Is a given value a string? + _.isString = function(obj) { + return !!(obj === '' || (obj && obj.charCodeAt && obj.substr)); + }; + + // Is a given value a number? + _.isNumber = function(obj) { + return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed)); + }; + + // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript + // that does not equal itself. + _.isNaN = function(obj) { + return obj !== obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false; + }; + + // Is a given value a date? + _.isDate = function(obj) { + return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear); + }; + + // Is the given value a regular expression? + _.isRegExp = function(obj) { + return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false)); + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; + + // Run a function **n** times. + _.times = function (n, iterator, context) { + for (var i = 0; i < n; i++) iterator.call(context, i); + }; + + // Add your own custom functions to the Underscore object, ensuring that + // they're correctly added to the OOP wrapper as well. + _.mixin = function(obj) { + each(_.functions(obj), function(name){ + addToWrapper(name, _[name] = obj[name]); + }); + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = idCounter++; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(str, data) { + var c = _.templateSettings; + var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + + 'with(obj||{}){__p.push(\'' + + str.replace(/\\/g, '\\\\') + .replace(/'/g, "\\'") + .replace(c.interpolate, function(match, code) { + return "'," + code.replace(/\\'/g, "'") + ",'"; + }) + .replace(c.evaluate || null, function(match, code) { + return "');" + code.replace(/\\'/g, "'") + .replace(/[\r\n\t]/g, ' ') + "__p.push('"; + }) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + + "');}return __p.join('');"; + var func = new Function('obj', tmpl); + return data ? func(data) : func; + }; + + // The OOP Wrapper + // --------------- + + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + var wrapper = function(obj) { this._wrapped = obj; }; + + // Expose `wrapper.prototype` as `_.prototype` + _.prototype = wrapper.prototype; + + // Helper function to continue chaining intermediate results. + var result = function(obj, chain) { + return chain ? _(obj).chain() : obj; + }; + + // A method to easily add functions to the OOP wrapper. + var addToWrapper = function(name, func) { + wrapper.prototype[name] = function() { + var args = slice.call(arguments); + unshift.call(args, this._wrapped); + return result(func.apply(_, args), this._chain); + }; + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + method.apply(this._wrapped, arguments); + return result(this._wrapped, this._chain); + }; + }); + + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + return result(method.apply(this._wrapped, arguments), this._chain); + }; + }); + + // Start chaining a wrapped Underscore object. + wrapper.prototype.chain = function() { + this._chain = true; + return this; + }; + + // Extracts the result from a wrapped and chained object. + wrapper.prototype.value = function() { + return this._wrapped; + }; + +})(); diff --git a/package.json b/package.json new file mode 100644 index 00000000..73369ba0 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name" : "jsdoc", + "description" : "Automated documentation generator for JavaScript", + "keywords" : ["jsdoc", "documentation"], + "homepage" : "http://micmath.github.com/jsdoc/", + "version" : "3.0.0a", + "author" : "Michael Mathews", + "repository" : { + "type" : "git", + "url" : "https://github.com/micmath/jsdoc.git" + }, + "maintainers" : [ + { + "name" : "Michael Mathews", + "email" : "micmath@gmail.com" + } + ], + "main" : "./jsdoc.js", + "bugs" : { + "web" : "https://github.com/micmath/jsdoc/issues" + }, + "directories" : { + "doc" : "./docs" + }, + "licenses" : [ + { + "type" : "MIT", + "url" : "http://www.opensource.org/licenses/mit-license.php" + } + ] +} \ No newline at end of file diff --git a/plugin/md.js b/plugin/md.js new file mode 100644 index 00000000..64f13f60 --- /dev/null +++ b/plugin/md.js @@ -0,0 +1,12 @@ +/** + @overview Converts the text of a doclet's description, from MarkDown to HTML. + */ + +var plugin = require('jsdoc/plugin'), + markdown = require('markdown/lib/markdown'); // TODO: allow rhino to use commonjs module id here + +plugin.manager.on('doclet', function(doclet) { + if (typeof doclet.description === 'string') { + doclet.description = markdown.toHTML(doclet.description); + } +}); \ No newline at end of file diff --git a/rhino_modules/fs/index.js b/rhino_modules/fs/index.js new file mode 100644 index 00000000..b01e60c2 --- /dev/null +++ b/rhino_modules/fs/index.js @@ -0,0 +1,67 @@ + +module.exports = { + readFileSync: function(filename, encoding, callback) { + if (typeof arguments[1] === 'function') { + encoding = null; + callback = arguments[1]; + } + + encoding = encoding || java.lang.System.getProperty('file.encoding'); + + try { + var content = new java.util.Scanner( + new java.io.File(filename), + encoding + ).useDelimiter("\\Z"); + + return String( content.next() ); + } + catch (e) { + throw('Cannot read module file '+filename); + } + + }, + readdirSync: function(path) { + var dir = new java.io.File(path); + if (!dir.directory) { return [String(dir)]; } + var files = dir.list(); + return files; + }, + + ls: function(dir, recurse, _allFiles, _path) { + var files, + file; + + if (typeof _path === 'undefined') { // initially + _allFiles = []; + _path = [dir]; + } + + if (_path.length === 0) { return _allFiles; } + if (typeof recurse === 'undefined') { recurse = 1; } + + files = this.readdirSync(dir); + + for (var f = 0, lenf = files.length; f < lenf; f++) { + file = String(files[f]); + + if (file.match(/^\.[^\.\/\\]/)) { continue; } // skip dot files + + if ((new java.io.File(_path.join('/') + '/' + file)).list()) { // it's a directory + _path.push(file); + + if (_path.length - 1 < recurse) { + exports.ls(_path.join('/'), recurse, _allFiles, _path); + } + _path.pop(); + } + else { // it's a file + _allFiles.push( + (_path.join('/') + '/' + file).replace(/[\/\\]+/g, '/') + ); + } + } + + return _allFiles; + } +}; \ No newline at end of file diff --git a/rhino_modules/path/index.js b/rhino_modules/path/index.js new file mode 100644 index 00000000..ebefaebf --- /dev/null +++ b/rhino_modules/path/index.js @@ -0,0 +1,9 @@ + +module.exports = { + 'basename' : function(path) { + var parts = path.split('/'); + parts.pop(); + path = parts.join('/'); + return path; + } +}; \ No newline at end of file diff --git a/rhino_modules/sys/index.js b/rhino_modules/sys/index.js new file mode 100644 index 00000000..f7d76464 --- /dev/null +++ b/rhino_modules/sys/index.js @@ -0,0 +1,6 @@ + +module.exports = { + 'puts' : function(str) { + print(String(str)); + } +}; \ No newline at end of file diff --git a/test-rhino.js b/test-rhino.js new file mode 100755 index 00000000..9c948f9f --- /dev/null +++ b/test-rhino.js @@ -0,0 +1,15 @@ +load('lib/rhino-shim.js'); +load('lib/nodeunit.js'); + +var fs = require('fs'), + testFiles = fs.ls('./test/'), + testFile; + +while ( testFile = testFiles.shift() ) { + var testName = testFile.replace(/\.js$/, ''); + var test = {}; + + test[testName] = require(testName); + + nodeunit.run(test); +} \ No newline at end of file diff --git a/test.js b/test.js new file mode 100644 index 00000000..df7a4ca7 --- /dev/null +++ b/test.js @@ -0,0 +1,8 @@ +#!/usr/bin/env node + +if (typeof load !== 'undefined') { + load('lib/rhino-shim.js'); +} + +var reporter = require('nodeunit').reporters['default']; +reporter.run(['./test']); \ No newline at end of file diff --git a/test/examples/only_comments.js b/test/examples/only_comments.js new file mode 100644 index 00000000..97b325ce --- /dev/null +++ b/test/examples/only_comments.js @@ -0,0 +1,2 @@ +/**@overview nothing but comments 1*/ +/**@overview nothing but comments 2*/ \ No newline at end of file diff --git a/test/jsdoc_parser.js b/test/jsdoc_parser.js new file mode 100644 index 00000000..416b1a30 --- /dev/null +++ b/test/jsdoc_parser.js @@ -0,0 +1,13 @@ +var parser = require('jsdoc/parser'); + +exports['The jsdoc parser should exist.'] = function(t) { + t.expect(1); + t.equal( typeof parser, 'object' ); + t.done(); +}; + +exports['The parser should have a parse function.'] = function(t) { + t.expect(1); + t.equal( typeof parser.parse, 'function' ); + t.done(); +}; diff --git a/test/jsdoc_parser_comments.js b/test/jsdoc_parser_comments.js new file mode 100644 index 00000000..7cd7f908 --- /dev/null +++ b/test/jsdoc_parser_comments.js @@ -0,0 +1,38 @@ +var parser = require('jsdoc/parser'); +var dumper = require('jsdoc/util/dumper'); + +exports['Parse a source containing only a jsdoc comment.'] = function(t) { + t.expect(1); + var docs = parser.parse('/**@doc*/'); + t.equal( docs.length, 1, 'should result in docs that contain the comment' ); + t.done(); +}; + +exports['Parse a source ending with a jsdoc comment.'] = function(t) { + t.expect(1); + var docs = parser.parse(';/**@doc*/'); + t.equal( docs.length, 1, 'should result in docs that contain the comment' ); + t.done(); +}; + +exports['Parse a source with a jsdoc comment preceding a jsdoc comment.'] = function(t) { + t.expect(1); + var docs = parser.parse('/**@doc1*/ /**@doc2*/ var x;'); + t.equal( docs.length, 2, 'should result in docs containing both the comments' ); + t.done(); +}; + +exports['Parse a source with only single line comments.'] = function(t) { + t.expect(1); + var docs = parser.parse('// foo'); + t.equal( docs.length, 0, 'should result in docs that are empty' ); + + t.done(); +}; + +exports['Parse a source with only single non-jsdoc multi-line comments.'] = function(t) { + t.expect(1); + var docs = parser.parse('/*foo*/'); + t.equal( docs.length, 0, 'should result in docs that are empty' ); + t.done(); +}; diff --git a/test/jsdoc_parser_function.js b/test/jsdoc_parser_function.js new file mode 100644 index 00000000..4d33c18b --- /dev/null +++ b/test/jsdoc_parser_function.js @@ -0,0 +1,29 @@ +var parser = require('jsdoc/parser'); + +exports['An undocumented named function.'] = function(t) { + t.expect(3); + var docs = parser.parse('function foo() {}'); + t.equal( docs.length, 1, 'should result in 1 doc' ); + t.equal( typeof docs[0].longname, 'string', 'should have a longname set' ); + t.equal( docs[0].longname, 'foo', 'should have a longname equal to the function name' ); + t.done(); +}; + +exports['A documented named function.'] = function(t) { + t.expect(4); + var docs = parser.parse('/**@desc a function*/ function foo() {}'); + t.equal( docs.length, 1, 'should result in 1 doc' ); + t.equal( docs[0].longname, 'foo', 'should have a longname equal to the function name' ); + t.equal( typeof docs[0].jsdoc, 'object', 'should have a jsdoc set' ); + t.equal( docs[0].jsdoc.src, '@desc a function', 'should have a jsdoc equal to the preceding doc comment' ); + t.done(); +}; + +exports['A nested documented named function.'] = function(t) { + t.expect(2); + var docs = parser.parse('function foo() { /**@desc a function*/ function bar() {} }'); + t.equal( docs.length, 2, 'should result in 2 docs' ); + t.equal( docs[1].longname, 'foo~bar', 'the inner function should have a longname equal to ~' ); + t.done(); +}; + diff --git a/test/narcissus.js b/test/narcissus.js new file mode 100644 index 00000000..aa062d9d --- /dev/null +++ b/test/narcissus.js @@ -0,0 +1,24 @@ +var narcissus = require('narcissus'); + +exports['Narcissus should exist.'] = function(t) { + t.expect(2); + t.equal( typeof narcissus, 'object' ); + t.equal( typeof narcissus.Narcissus, 'object' ); + t.done(); +}; + +exports['Narcissus parse should be a function.'] = function(t) { + t.expect(2); + t.equal( typeof narcissus.Narcissus.parser, 'object' ); + t.equal( typeof narcissus.Narcissus.parser.parse, 'function' ); + t.done(); +}; + +exports['Narcissus parse should generate an AST from source.'] = function(t) { + t.expect(1); + var src = 'var foo = 1;', + ast = narcissus.Narcissus.parser.parse(src, 'filename', 1); + + t.equal( typeof ast, 'object' ); + t.done(); +}; \ No newline at end of file