Comparing version 0.0.1 to 0.0.2
{ | ||
"name": "libyaml", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "Bindings to libYAML", | ||
@@ -5,0 +5,0 @@ |
**YAML.node** is a quick and dirty binding for LibYAML. | ||
To use, make sure libYAML headers are installed, and then: | ||
$ npm install libyaml | ||
$ node | ||
> yaml = require('libyaml'); | ||
> yaml.load('Hello world!'); | ||
To manually build and run the simple test: | ||
node-waf configure build | ||
LD_LIBRARY_PATH=. coffee ./test.coffee |
127
yaml.js
@@ -110,63 +110,89 @@ // YAML.node, © 2010 Stéphan Kochen | ||
// array of documents found represented as plain JavaScript objects, arrays and primitives. | ||
exports.load = function(input) { | ||
var documents = [], | ||
document; | ||
exports.load = function(input, tagHandlers) { | ||
if (typeof tagHandlers !== 'object') | ||
tagHandlers = {}; | ||
// A stack of value handlers, as they occur. | ||
// Document, sequence and mapping events add functions to this stack. | ||
var stack = [], | ||
newValue = function(v) { | ||
stack[0](v); | ||
}, | ||
pushHandler = function(h) { | ||
stack.unshift(h); | ||
}, | ||
popHandler = function() { | ||
stack.shift(); | ||
}; | ||
var parserHandler, handlerStack = []; | ||
// Capture all values between two parser events. Because we can nest in YAML, we need a stack of | ||
// these value handlers, and we need to ensure we can deal with `until` blocks that are nested | ||
// for the same kinds of events (ie. restore the old event handler afterwards). | ||
var until = function(method, valueHandler) { | ||
var oldMethod = parserHandler[method]; | ||
handlerStack.unshift(valueHandler); | ||
parserHandler[method] = function(e) { | ||
parserHandler[method] = oldMethod; | ||
var oldHandler = handlerStack.shift(); | ||
oldHandler.after(); | ||
}; | ||
}; | ||
// Dispatch a value. At this point, the value is a JavaScript primitive, ie. sequences are | ||
// `Array`s, numeric scalars are `Number`s, etc. If a tag was specified, the tag handler | ||
// function is asked to post process the value. The value is then sent to the current value | ||
// handler in the stack. | ||
var dispatch = function(e, value) { | ||
if (e.tag !== null) { | ||
var tagHandler = tagHandlers[e.tag]; | ||
// FIXME: Deal with standard tags | ||
if (tagHandler) | ||
value = tagHandler(value); | ||
} | ||
handlerStack[0].handle(value); | ||
}; | ||
// Call into the parser and build the documents. | ||
// FIXME: Handle tags and anchors. | ||
binding.parse(input, { | ||
var documents = []; | ||
binding.parse(input, parserHandler = { | ||
onDocumentEnd: null, | ||
onDocumentStart: function(e) { | ||
pushHandler(function(v) { | ||
document = v; | ||
var document; | ||
until('onDocumentEnd', { | ||
handle: function(value) { | ||
document = value; | ||
}, | ||
after: function() { | ||
documents.push(document); | ||
} | ||
}); | ||
}, | ||
onDocumentEnd: function(e) { | ||
popHandler(); | ||
documents.push(document); | ||
onAlias: function(e) { | ||
// FIXME | ||
}, | ||
onScalar: function(e) { | ||
newValue(parseScalar(e.value)); | ||
dispatch(e, parseScalar(e.value)); | ||
}, | ||
onSequenceEnd: null, | ||
onSequenceStart: function(e) { | ||
var sequence = []; | ||
newValue(sequence); | ||
pushHandler(function(v) { | ||
sequence.push(v); | ||
until('onSequenceEnd', { | ||
handle: function(value) { | ||
sequence.push(value); | ||
}, | ||
after: function() { | ||
dispatch(e, sequence); | ||
} | ||
}); | ||
}, | ||
onSequenceEnd: function(e) { | ||
popHandler(); | ||
}, | ||
onMappingEnd: null, | ||
onMappingStart: function(e) { | ||
var mapping = {}, | ||
key, | ||
keyHandler = function(v) { | ||
key = v; | ||
pushHandler(valueHandler); | ||
}, | ||
valueHandler = function(v) { | ||
mapping[key] = v; | ||
popHandler(); | ||
}; | ||
newValue(mapping); | ||
pushHandler(keyHandler); | ||
}, | ||
onMappingEnd: function(e) { | ||
popHandler(); | ||
var mapping = {}, key = undefined; | ||
until('onMappingEnd', { | ||
handle: function(value) { | ||
if (key === undefined) { | ||
key = value; | ||
} | ||
else { | ||
mapping[key] = value; | ||
key = undefined; | ||
} | ||
}, | ||
after: function() { | ||
dispatch(e, mapping); | ||
} | ||
}); | ||
} | ||
@@ -179,6 +205,11 @@ }); | ||
// Helper for quickly reading in a file. | ||
exports.loadFile = function(filename, callback) { | ||
exports.loadFile = function(filename, tagHandlers, callback) { | ||
if (typeof tagHandlers === 'function') { | ||
callback = tagHandlers; | ||
tagHandlers = {}; | ||
} | ||
fs.readFile(filename, 'utf-8', function(err, data) { | ||
if (err) callback(err, null); | ||
else callback(null, exports.load(data)); | ||
else callback(null, exports.load(data, tagHandlers)); | ||
}); | ||
@@ -188,5 +219,5 @@ }; | ||
// Synchronous version of loadFile. | ||
exports.loadFileSync = function(filename) { | ||
exports.loadFileSync = function(filename, tagHandlers) { | ||
var data = fs.readFileSync(filename, 'utf-8'); | ||
return exports.load(data); | ||
return exports.load(data, tagHandlers); | ||
}; | ||
@@ -193,0 +224,0 @@ |
Sorry, the diff of this file is not supported yet
30241
252
14