pax_global_header00006660000000000000000000000064125272267760014532gustar00rootroot0000000000000052 comment=9e67bcad6823846861c74af03bc18a7dba379d0b yamlish-0.0.7/000077500000000000000000000000001252722677600132045ustar00rootroot00000000000000yamlish-0.0.7/LICENSE000066400000000000000000000013751252722677600142170ustar00rootroot00000000000000The ISC License Copyright (c) Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. yamlish-0.0.7/README.md000066400000000000000000000006701252722677600144660ustar00rootroot00000000000000This is a thingie to parse the "yamlish" format used to serialize objects in the TAP format. It's like yaml, but just a tiny little bit smaller. Usage: var yamlish = require("yamlish") // returns a string like: /* some: object: - full - of pretty: things */ yamlish.encode({some:{object:["full", "of"]}, pretty:"things"}) // returns the object yamlish.decode(someYamlishString) yamlish-0.0.7/package.json000066400000000000000000000005621252722677600154750ustar00rootroot00000000000000{ "name": "yamlish", "description": "Parser/encoder for the yamlish format", "repository": "https://github.com/isaacs/yamlish", "version": "0.0.7", "main": "yamlish.js", "keywords": [ "yaml", "yamlish", "test", "anything", "protocol", "tap" ], "license": "ISC", "author": "Isaac Z. Schlueter (http://blog.izs.me/)" } yamlish-0.0.7/yamlish.js000066400000000000000000000152121252722677600152110ustar00rootroot00000000000000exports.encode = encode exports.decode = decode var seen = [] function encode (obj, indent) { var deep = arguments[2] if (!indent) indent = " " if (obj instanceof String || Object.prototype.toString.call(obj) === "[object String]") { obj = obj.toString() } if (obj instanceof Number || Object.prototype.toString.call(obj) === "[object Number]") { obj = obj.valueOf() } // take out the easy ones. switch (typeof obj) { case "string": obj = obj.trim() if (/[:\n\[\]]/g.test(obj)) { return "|\n" + indent + obj.split(/\r?\n/).join("\n"+indent) } else { return (obj) } case "number": return obj.toString(10) case "function": return encode(obj.toString(), indent, true) case "boolean": return obj.toString() case "undefined": // fallthrough case "object": // at this point we know it types as an object if (!obj) return "~" if (obj instanceof Date || Object.prototype.toString.call(obj) === "[object Date]") { return JSON.stringify("[Date " + obj.toISOString() + "]") } if (obj instanceof RegExp || Object.prototype.toString.call(obj) === "[object RegExp]") { return JSON.stringify(obj.toString()) } if (obj instanceof Boolean || Object.prototype.toString.call(obj) === "[object Boolean]") { return obj.toString() } if (seen.indexOf(obj) !== -1) { return "[Circular]" } seen.push(obj) if (typeof Buffer === "function" && typeof Buffer.isBuffer === "function" && Buffer.isBuffer(obj)) return obj.inspect() if (obj instanceof Error) { var o = { name: obj.name , message: obj.message , type: obj.type } if (obj.code) o.code = obj.code if (obj.errno) o.errno = obj.errno if (obj.type) o.type = obj.type obj = o } var out = "" if (Array.isArray(obj)) { var out = "\n" + indent + "- " +obj.map(function (item) { return encode(item, indent + " ", true) }).join("\n"+indent + "- ") break } // an actual object var keys = Object.keys(obj) , niceKeys = keys.map(function (k) { return (k.match(/^[a-zA-Z0-9_]+$/) ? k : JSON.stringify(k)) + ": " }) //console.error(keys, niceKeys, obj) var maxLength = Math.max.apply(Math, niceKeys.map(function (k) { return k.length }).concat(0)) //console.error(niceKeys, maxLength) var spaces = new Array(maxLength + 1).join(" ") if (!deep) indent += " " out = "\n" + indent + keys.map(function (k, i) { var niceKey = niceKeys[i] return niceKey + spaces.substr(niceKey.length) + encode(obj[k], indent + " ", true) }).join("\n" + indent) break default: return "" } if (!deep) seen.length = 0 return out } function decode (str) { var v = str.trim() , d , dateRe = /^\[Date ([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}(?::[0-9]{2})?(?:\.[0-9]{3})?(?:[A-Z]+)?)\]$/ if (v === "~") return null try { var jp = JSON.parse(str) } catch (e) { var jp = "" } if (jp && typeof jp === "string" && (d = jp.match(dateRe)) && (d = Date.parse(d[1]))) { return new Date(d) } if (typeof jp === "boolean") return jp if (v && !isNaN(v)) return parseInt(v, 10) // something interesting. var lines = str.split(/\r?\n/) // check if it's some kind of string or something. // if the first line is > or | then it's a wrapping indented string. // if the first line is blank, and there are many lines, // then it's an array or object. // otherwise, it's just "" var first = lines.shift().trim() if (lines.length) lines = undent(lines) switch (first) { case "|": return lines.join("\n") case ">": return lines.join("\n").split(/\n{2,}/).map(function (l) { return l.split(/\n/).join(" ") }).join("\n") default: if (!lines.length) return first // array or object. // the first line will be either "- value" or "key: value" return lines[0].charAt(0) === "-" ? decodeArr(lines) : decodeObj(lines) } } function decodeArr (lines) { var out = [] , key = 0 , val = [] for (var i = 0, l = lines.length; i < l; i ++) { // if it starts with a -, then it's a new thing var line = lines[i] if (line.charAt(0) === "-") { if (val.length) { out[key ++] = decode(val.join("\n")) val.length = 0 } val.push(line.substr(1).trim()) } else if (line.charAt(0) === " ") { val.push(line) } else return [] } if (val.length) { out[key ++] = decode(val.join("\n")) } return out } function decodeObj (lines) { var out = {} , val = [] , key = null for (var i = 0, l = lines.length; i < l; i ++) { var line = lines[i] if (line.charAt(0) === " ") { val.push(line) continue } // some key:val if (val.length) { out[key] = decode(val.join("\n")) val.length = 0 } // parse out the quoted key var first if (line.charAt(0) === "\"") { for (var ii = 1, ll = line.length, esc = false; ii < ll; ii ++) { var c = line.charAt(ii) if (c === "\\") { esc = !esc } else if (c === "\"" && !esc) { break } } key = JSON.parse(line.substr(0, ii + 1)) line = line.substr(ii + 1) first = line.substr(line.indexOf(":") + 1).trim() } else { var kv = line.split(":") key = kv.shift() first = kv.join(":").trim() } // now we've set a key, and "first" has the first line of the value. val.push(first.trim()) } if (val.length) out[key] = decode(val.join("\n")) return out } function undent (lines) { var i = lines[0].match(/^\s*/)[0].length return lines.map(function (line) { return line.substr(i) }) } // XXX Turn this into proper tests. if (require.main === module) { var obj = [{"bigstring":new Error().stack} ,{ar:[{list:"of"},{some:"objects"}]} ,{date:new Date()} ,{"super huge string":new Error().stack} ] Date.prototype.toJSON = function (k, val) { console.error(k, val, this) return this.toISOString() + " (it's a date)" } var enc = encode(obj) , dec = decode(enc) , encDec = encode(dec) console.error(JSON.stringify({ obj : obj , enc : enc.split(/\n/) , dec : dec }, null, 2), encDec === enc) var num = 100 , encNum = encode(num) , decEncNum = decode(encNum) console.error([num, encNum, decEncNum]) }