pax_global_header00006660000000000000000000000064123724745670014533gustar00rootroot0000000000000052 comment=fbb89dc1c2d1b53feb07f7130f1fd0e4e402b718 yamlish-0.0.6/000077500000000000000000000000001237247456700132045ustar00rootroot00000000000000yamlish-0.0.6/LICENSE000066400000000000000000000020611237247456700142100ustar00rootroot00000000000000Copyright (c) 2011 Isaac Z. Schlueter 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. yamlish-0.0.6/README.md000066400000000000000000000006701237247456700144660ustar00rootroot00000000000000This 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.6/package.json000066400000000000000000000007061237247456700154750ustar00rootroot00000000000000{ "name": "yamlish", "description": "Parser/encoder for the yamlish format", "repository": "https://github.com/isaacs/yamlish", "version": "0.0.6", "main": "yamlish.js", "keywords": [ "yaml", "yamlish", "test", "anything", "protocol", "tap" ], "license": { "type": "MIT", "url": "http://github.com/isaacs/yamlish/raw/master/LICENSE" }, "author": "Isaac Z. Schlueter (http://blog.izs.me/)" } yamlish-0.0.6/yamlish.js000066400000000000000000000152121237247456700152110ustar00rootroot00000000000000exports.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]) }