json5-utils
Advanced tools
Comparing version 0.3.0 to 0.3.1
@@ -10,2 +10,6 @@ /* | ||
function isObject(x) { | ||
return typeof(x) === 'object' && x !== null | ||
} | ||
function Document(text, options) { | ||
@@ -15,5 +19,8 @@ if (!(this instanceof Document)) return new Document(text) | ||
if (options == null) options = {} | ||
options._structure = true | ||
//options._structure = true | ||
var tokens = this._tokens = [] | ||
options._tokenize = function(smth) { | ||
tokens.push(smth) | ||
} | ||
this._data = parse(text, options) | ||
if (this._data === undefined) this._data = {} | ||
this._commands = [] | ||
@@ -34,9 +41,9 @@ } | ||
if (typeof(path) === 'string') path = path.split('.') | ||
var data = this._data | ||
for (var i=0; i<path.length; i++) { | ||
if (data[path[i]] == null) return undefined | ||
if (!isObject(data)) return undefined | ||
data = data[path[i]] | ||
} | ||
return data.value | ||
return data | ||
} | ||
@@ -50,10 +57,12 @@ | ||
for (var i=0; i<path.length; i++) { | ||
if (data[path[i]] == null) return false | ||
if (!isObject(data)) return false | ||
data = data[path[i]] | ||
} | ||
return true | ||
return data !== undefined | ||
} | ||
Document.prototype.toString = function() { | ||
return this._tokens.map(function(x) { | ||
return x.raw | ||
}).join('') | ||
} | ||
@@ -60,0 +69,0 @@ |
162
lib/parse.js
@@ -73,19 +73,31 @@ /* | ||
var valueStart = function() {} | ||
var valueEnd = function(v) {return v} | ||
var tokenStart = function() {} | ||
var tokenEnd = function(v) {return v} | ||
if (options._structure) { | ||
/* tokenize({ | ||
raw: '...', | ||
type: 'whitespace'|'comment'|'literal'|'separator', | ||
value: 'number'|'string'|'whatever', | ||
path: [...], | ||
}) | ||
*/ | ||
if (options._tokenize) { | ||
;(function() { | ||
var indent | ||
valueStart = function() { | ||
var start = null | ||
tokenStart = function() { | ||
if (start !== null) throw new Error('internal error, token overlap') | ||
start = position | ||
} | ||
valueEnd = function(v) { | ||
if (v === undefined) return undefined | ||
return { | ||
indent: indent, | ||
value: v, | ||
tokenEnd = function(v, type) { | ||
if (start != position) { | ||
var hash = { | ||
raw: input.substr(start, position-start), | ||
type: type, | ||
} | ||
if (v !== undefined) hash.value = v | ||
options._tokenize.call(null, hash) | ||
} | ||
start = null | ||
return v | ||
} | ||
@@ -120,29 +132,28 @@ })() | ||
function newline(chr) { | ||
// account for <cr><lf> | ||
if (chr === '\r' && input[position] === '\n') position++ | ||
linestart = position | ||
lineno++ | ||
} | ||
function parseGeneric(is_key) { | ||
var result | ||
//console.log('parse: =============\n', input.substr(position, 40)) | ||
skipWhiteSpace() | ||
while (position < length) { | ||
tokenStart() | ||
var chr = input[position++] | ||
if (Uni.isLineTerminator(chr)) { | ||
// account for <cr><lf> | ||
if (chr === '\r' && input[position] === '\n') position++ | ||
linestart = position | ||
lineno++ | ||
if (chr === '"' || (chr === '\'' && !legacy)) { | ||
return tokenEnd(parseString(chr), 'literal') | ||
} else if (Uni.isWhiteSpace(chr)) { | ||
// nothing | ||
} else if (chr === '"' || (chr === '\'' && !legacy)) { | ||
valueStart() | ||
return valueEnd(parseString(chr)) | ||
} else if (chr === '{') { | ||
valueStart() | ||
return valueEnd(parseObject()) | ||
tokenEnd(undefined, 'separator') | ||
return parseObject() | ||
} else if (chr === '[') { | ||
valueStart() | ||
return valueEnd(parseArray()) | ||
tokenEnd(undefined, 'separator') | ||
return parseArray() | ||
@@ -155,26 +166,16 @@ } else if (chr === '-' | ||
) { | ||
valueStart() | ||
return valueEnd(parseNumber(is_key)) | ||
return tokenEnd(parseNumber(is_key), 'literal') | ||
} else if (chr === 'n' && !is_key) { | ||
valueStart() | ||
parseKeyword('null') | ||
return valueEnd(null) | ||
return tokenEnd(null, 'literal') | ||
} else if (chr === 't' && !is_key) { | ||
valueStart() | ||
parseKeyword('true') | ||
return valueEnd(true) | ||
return tokenEnd(true, 'literal') | ||
} else if (chr === 'f' && !is_key) { | ||
valueStart() | ||
parseKeyword('false') | ||
return valueEnd(false) | ||
return tokenEnd(false, 'literal') | ||
} else if (chr === '/' | ||
&& !legacy | ||
&& (input[position] === '/' || input[position] === '*') | ||
) { | ||
skipComment(input[position++] === '*') | ||
} else if (!legacy | ||
@@ -184,3 +185,2 @@ && is_key | ||
// unicode char or a unicode sequence | ||
valueStart() | ||
var rollback = position - 1 | ||
@@ -191,5 +191,5 @@ var result = parseIdentifier() | ||
position = rollback | ||
return valueEnd(undefined) | ||
return tokenEnd(undefined) | ||
} else { | ||
return valueEnd(result) | ||
return tokenEnd(result, 'literal') | ||
} | ||
@@ -199,3 +199,3 @@ | ||
position-- | ||
return | ||
return tokenEnd(undefined) | ||
} | ||
@@ -205,2 +205,33 @@ } | ||
function skipWhiteSpace() { | ||
tokenStart() | ||
while (position < length) { | ||
var chr = input[position++] | ||
if (Uni.isLineTerminator(chr)) { | ||
newline(chr) | ||
} else if (Uni.isWhiteSpace(chr)) { | ||
// nothing | ||
} else if (chr === '/' | ||
&& !legacy | ||
&& (input[position] === '/' || input[position] === '*') | ||
) { | ||
position-- | ||
tokenEnd(undefined, 'whitespace') | ||
tokenStart() | ||
position++ | ||
skipComment(input[position++] === '*') | ||
tokenEnd(undefined, 'comment') | ||
tokenStart() | ||
} else { | ||
position-- | ||
break | ||
} | ||
} | ||
return tokenEnd(undefined, 'whitespace') | ||
} | ||
function skipComment(multi) { | ||
@@ -211,6 +242,3 @@ while (position < length) { | ||
if (Uni.isLineTerminator(chr)) { | ||
// account for <cr><lf> | ||
if (chr === '\r' && input[position] === '\n') position++ | ||
linestart = position | ||
lineno++ | ||
newline(chr) | ||
@@ -252,7 +280,6 @@ // LineTerminator is an end of singleline comment | ||
var item1 = parseGeneric(!legacy) | ||
var whitespace = parseGeneric() | ||
if (whitespace !== undefined) fail('Unexpected literal: ' + JSON.stringify(whitespace)) | ||
skipWhiteSpace() | ||
tokenStart() | ||
var chr = input[position++] | ||
tokenEnd(undefined, 'separator') | ||
@@ -274,3 +301,3 @@ if (chr === '}' && item1 === undefined) { | ||
if (options.duplicate_keys === 'throw') { | ||
fail('duplicate key: ' + item1) | ||
fail('Duplicate key: ' + item1) | ||
} else { | ||
@@ -294,6 +321,8 @@ // silently ignore it | ||
var whitespace = parseGeneric() | ||
if (whitespace !== undefined) fail('Unexpected literal: ' + whitespace) | ||
skipWhiteSpace() | ||
tokenStart() | ||
var chr = input[position++] | ||
tokenEnd(undefined, 'separator') | ||
if (chr === ',') { | ||
@@ -310,2 +339,3 @@ continue | ||
} else { | ||
position-- | ||
fail() | ||
@@ -323,7 +353,6 @@ } | ||
var item = parseGeneric() | ||
var whitespace = parseGeneric() | ||
if (whitespace !== undefined) fail('Unexpected literal: ' + whitespace) | ||
skipWhiteSpace() | ||
tokenStart() | ||
var chr = input[position++] | ||
tokenEnd(undefined, 'separator') | ||
@@ -351,2 +380,3 @@ if (item !== undefined) { | ||
} else { | ||
position-- | ||
fail() | ||
@@ -500,7 +530,5 @@ } | ||
} else if (Uni.isLineTerminator(chr)) { | ||
// line continuation, do nothing | ||
// line continuation | ||
newline(chr) | ||
// cr+lf | ||
if (chr === '\r' && input[position] === '\n') position++ | ||
} else if (chr === 'u' || chr === 'x') { | ||
@@ -545,5 +573,5 @@ // unicode/character escape sequence | ||
if (result !== undefined) { | ||
var result2 = parseGeneric() | ||
skipWhiteSpace() | ||
if (result2 === undefined && position >= length) { | ||
if (position >= length) { | ||
if (typeof(options.reviver) === 'function') { | ||
@@ -550,0 +578,0 @@ result = options.reviver.call(null, '', result) |
@@ -1,1 +0,1 @@ | ||
{"name":"json5-utils","version":"0.3.0","description":"JSON/JSON5 parser and serializer","author":{"name":"Alex Kocharin","email":"alex@kocharin.ru"},"repository":{"type":"git","url":"git://github.com/rlidwka/json5-utils"},"bugs":{"url":"https://github.com/rlidwka/json5-utils/issues"},"main":"parse.js","scripts":{"test":"node test/test.js"},"keywords":["json","json5","parser"],"license":"WTFPL"} | ||
{"name":"json5-utils","version":"0.3.1","description":"JSON/JSON5 parser and serializer","author":{"name":"Alex Kocharin","email":"alex@kocharin.ru"},"repository":{"type":"git","url":"git://github.com/rlidwka/json5-utils"},"bugs":{"url":"https://github.com/rlidwka/json5-utils/issues"},"main":"parse.js","devDependencies":{"mocha":"*"},"scripts":{"test":"mocha test/*.js"},"keywords":["json","json5","parser"],"license":"WTFPL"} |
@@ -1,7 +0,47 @@ | ||
// not yet developed | ||
/*var assert = require('assert') | ||
var assert = require('assert') | ||
var create = require('../lib/document').Document | ||
assert.equal(create('"test"').get(''), 'test') | ||
var str = '{ x\r\n:\n1, y: {"..z.": 123, t: null, s:"123", a:[ 1,2,{x:3},] }}\n' | ||
var d = create(str) | ||
assert.equal(d + '', str) | ||
assert.deepEqual(d.get(''), {x:1,y:{'..z.':123,t:null,s:'123',a:[1,2,{x:3}]}}) | ||
assert.deepEqual(d.get('x'), 1) | ||
assert.deepEqual(d.get('x.x'), undefined) | ||
assert.deepEqual(d.get('x.x.x.x'), undefined) | ||
assert.strictEqual(d.get('y.x'), undefined) | ||
assert.deepEqual(d.get('y.s'), '123') | ||
assert.strictEqual(d.get('y.t'), null) | ||
assert.strictEqual(d.get('y.t.x'), undefined) | ||
assert.equal(d.has(''), true) | ||
assert.equal(d.has('x'), true) | ||
assert.equal(d.has('x.x'), false) | ||
assert.equal(d.has('x.x.x.x'), false) | ||
assert.equal(d.has('y.x'), false) | ||
assert.equal(d.has('y'), true) | ||
assert.equal(d.has('y.s'), true) | ||
assert.equal(d.has('y.t'), true) | ||
assert.equal(d.has('a'), false) | ||
// arrays | ||
assert.deepEqual(d.get('y.a'), [1,2,{x:3}]) | ||
assert.deepEqual(d.get('y.a.0'), 1) | ||
assert.deepEqual(d.get('y.a.2.x'), 3) | ||
assert.deepEqual(d.get('y.a.10'), undefined) | ||
assert.deepEqual(d.has('y.a.0'), true) | ||
assert.deepEqual(d.has('y.a.10'), false) | ||
assert.deepEqual(d.get('y.a.2'), {x:3}) | ||
// controversial | ||
assert.strictEqual(d.get('y.s.0'), undefined) | ||
assert.equal(d.has('y.s.0'), false) | ||
// paths | ||
assert.deepEqual(d.get([]), {x:1,y:{'..z.':123,t:null,s:'123',a:[1,2,{x:3}]}}) | ||
assert.strictEqual(d.has([]), true) | ||
assert.strictEqual(d.get(['y','..z.']), 123) | ||
assert.strictEqual(d.has(['y','..z.']), true) | ||
assert.deepEqual(d.get(['y','a',2,'x']), 3) | ||
/*assert.equal(create('"test"').get(''), 'test') | ||
assert.equal(create('"test"').get([]), 'test') | ||
@@ -8,0 +48,0 @@ assert.equal(create('"test"').get(false), 'test') |
@@ -6,14 +6,22 @@ | ||
function addTest(arg) { | ||
//console.log('testing: ', arg) | ||
try { | ||
var x = parse(arg) | ||
} catch(err) { | ||
x = 'fail' | ||
function fn() { | ||
//console.log('testing: ', arg) | ||
try { | ||
var x = parse(arg) | ||
} catch(err) { | ||
x = 'fail' | ||
} | ||
try { | ||
var z = eval('(function(){"use strict"\nreturn ('+String(arg)+'\n)\n})()') | ||
} catch(err) { | ||
z = 'fail' | ||
} | ||
assert.deepEqual(x, z) | ||
} | ||
try { | ||
var z = eval('(function(){"use strict"\nreturn ('+String(arg)+'\n)\n})()') | ||
} catch(err) { | ||
z = 'fail' | ||
if (typeof(describe) === 'function') { | ||
it('test_parse: ' + JSON.stringify(arg), fn) | ||
} else { | ||
fn() | ||
} | ||
assert.deepEqual(x, z) | ||
} | ||
@@ -58,2 +66,13 @@ | ||
// whitespaces | ||
addTest('[1,\r\n2,\r3,\n]') | ||
'\u0020\u00A0\uFEFF\x09\x0A\x0B\x0C\x0D\u0085\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000'.split('').forEach(function(x) { | ||
addTest(x+'[1,'+x+'2]'+x) | ||
addTest('"'+x+'"'+x) | ||
}) | ||
'\u000A\u000D\u2028\u2029'.split('').forEach(function(x) { | ||
addTest(x+'[1,'+x+'2]'+x) | ||
addTest('"\\'+x+'"'+x) | ||
}) | ||
if (process.version > 'v0.11.7') { | ||
@@ -60,0 +79,0 @@ assert(Array.isArray(parse('{__proto__:[]}').__proto__)) |
@@ -14,4 +14,12 @@ | ||
function addTest(arg, arg2, arg3) { | ||
deepEqual(parse(stringify(arg)), arg2 === undefined ? arg : arg2) | ||
if (arg !== undefined) deepEqual(JSON.parse(stringify(arg, {mode: 'json', indent: false})), (arg3 === undefined ? (arg2 === undefined ? arg : arg2) : arg3)) | ||
function fn() { | ||
deepEqual(parse(stringify(arg)), arg2 === undefined ? arg : arg2) | ||
if (arg !== undefined) deepEqual(JSON.parse(stringify(arg, {mode: 'json', indent: false})), (arg3 === undefined ? (arg2 === undefined ? arg : arg2) : arg3)) | ||
} | ||
if (typeof(describe) === 'function') { | ||
it('test_stringify: ' + JSON.stringify(arg), fn) | ||
} else { | ||
fn() | ||
} | ||
} | ||
@@ -18,0 +26,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
83863
20
1498
1