1 // Based on the work of Tj Holowaychuk
  2 // http://refactormycode.com/codes/1045-js-yaml-parser
  3 //
  4 // This implementation is not complete
  5 
  6 rio.Yaml = {
  7 	dump: function(obj, indent) {
  8 		indent = indent || 0;
  9 		var indentText = "  ".times(indent);
 10 
 11 		if (Object.isArray(obj)) {
 12 			return obj.map(function(item) {
 13 				return indentText + "- " + item;
 14 			}.bind(this)).join("\n");
 15 		} else {
 16 			return Object.keys(obj).map(function(k) {
 17 				var val = obj[k];
 18 				if (this._isPrimitive(val)) {
 19 					return indentText + k + ": " + val;
 20 				} else {
 21 					return indentText + k + ":\n" + this.dump(obj[k], indent + 1);
 22 				}
 23 			}.bind(this)).join("\n");
 24 		}
 25 	},
 26 
 27 	parse: function(str) {
 28 		return this._parse(this._tokenize(str));
 29 	},
 30 	
 31 	_isPrimitive: function(val) {
 32 		return Object.isNumber(val) || Object.isString(val);
 33 	},
 34 
 35 	_valueOf: function(token) {
 36 		try {
 37 			return eval('(' + token + ')');
 38 		} catch(e) {
 39 			return token;
 40 		}
 41 	},
 42 
 43 	_tokenize: function(str) {
 44 		return str.match(/(---|true|false|null|#(.*)|\[(.*?)\]|\{(.*?)\}|[^\w\n]*[\/\.\w\-]+:|[^\w\n]*-(.+)|\d+\.\d+|\d+|\n+|\w.+)/g);
 45 	},
 46 
 47 	_indentLevel: function(token) {
 48 		return token ? Math.max(token.match(/^(\t*).*/)[1].length, token.match(/^([\s]*).*/)[1].length / 2) : 0;
 49 	},
 50 
 51 	_parse: function(tokens) {
 52 		while(tokens[0] == "\n") { tokens.shift(); }
 53 
 54 		var token, list = /-(.*)/, key = /([\/\.\w\-]+):/, stack = {};
 55 		
 56 		var indentLevel = this._indentLevel(tokens[0]);
 57 		
 58 		while (tokens[0] && (this._indentLevel(tokens[0]) >= indentLevel || tokens[0] == "\n")) {
 59 			token = tokens.shift();
 60 			if (token[0] == '#' || token == '---' || token == "\n") {
 61 				continue;
 62 			} else if (key.exec(token)) {
 63 				var keyName = RegExp.$1.strip();
 64 				if (tokens[0] == "\n") {
 65 					tokens.shift();
 66 					stack[keyName] = this._parse(tokens);
 67 				} else {
 68 					stack[keyName] = this._valueOf(tokens.shift());
 69 				}
 70 			} else if (list.exec(token)) {
 71 				(Object.isArray(stack) ? stack : (stack = [])).push(RegExp.$1.strip());
 72 			}
 73 		}
 74 		return stack;
 75 	},
 76 
 77 	toString: function() {
 78 		return "Yaml";
 79 	}
 80 };
 81