Comparing version 0.0.0 to 0.0.1
173
json5.js
@@ -7,3 +7,5 @@ // json5.js | ||
exports.parse = (function () { | ||
var JSON5 = (typeof exports === 'object' ? exports : {}); | ||
JSON5.parse = (function () { | ||
"use strict"; | ||
@@ -14,3 +16,3 @@ | ||
// eval or regular expressions, so it can be used as a model for implementing | ||
// a JSON parser in other languages. | ||
// a JSON5 parser in other languages. | ||
@@ -23,5 +25,7 @@ // We are defining the function inside of another function to avoid creating | ||
escapee = { | ||
"'": "'", | ||
'"': '"', | ||
'\\': '\\', | ||
'/': '/', | ||
'\n': '', // Replace newlines in strings w/ empty string | ||
b: '\b', | ||
@@ -63,2 +67,27 @@ f: '\f', | ||
identifier = function () { | ||
// Parse an identifier. Normally, reserved words are disallowed here, but we | ||
// only use this for unquoted object keys, where reserved words are allowed, | ||
// so we don't check for those here. References: | ||
// - http://es5.github.com/#x7.6 | ||
// - https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Variables | ||
// - http://docstore.mik.ua/orelly/webprog/jscript/ch02_07.htm | ||
// TODO Identifiers can have Unicode "letters" in them; add support for those. | ||
var key = ch; | ||
// Identifiers must start with a letter, _ or $. | ||
if (!ch.match(/^[a-zA-Z_$]$/)) { | ||
error("Bad identifier"); | ||
} | ||
// Subsequent characters can contain digits. | ||
while (next() && ch.match(/^[\w$]$/)) { | ||
key += ch; | ||
} | ||
return key; | ||
}, | ||
number = function () { | ||
@@ -112,2 +141,3 @@ | ||
string = '', | ||
delim, // double quote or single quote | ||
uffff; | ||
@@ -117,5 +147,6 @@ | ||
if (ch === '"') { | ||
if (ch === '"' || ch === "'") { | ||
delim = ch; | ||
while (next()) { | ||
if (ch === '"') { | ||
if (ch === delim) { | ||
next(); | ||
@@ -148,11 +179,84 @@ return string; | ||
white = function () { | ||
inlineComment = function () { | ||
// Skip whitespace. | ||
// Skip inline comments, assuming this is one. The current character should be | ||
// the second / character in the // pair that begins this inline comment. | ||
// When parsing inline comments, we look for a newline or the end of the text. | ||
while (ch && ch <= ' ') { | ||
if (ch !== '/') { | ||
error("Not an inline comment"); | ||
} | ||
do { | ||
next(); | ||
if (ch === '\n') { | ||
next('\n'); | ||
return; | ||
} | ||
} while (ch); | ||
}, | ||
blockComment = function () { | ||
// Skip block comments, assuming this is one. The current character should be | ||
// the * character in the /* pair that begins this block comment. | ||
// When parsing block comments, we look for an ending */ pair of characters, | ||
// but we also watch for the end of text before the comment is terminated. | ||
if (ch !== '*') { | ||
error("Not a block comment"); | ||
} | ||
do { | ||
next(); | ||
while (ch === '*') { | ||
next('*'); | ||
if (ch === '/') { | ||
next('/'); | ||
return; | ||
} | ||
} | ||
} while (ch); | ||
error("Unterminated block comment"); | ||
}, | ||
comment = function () { | ||
// Skip comments, both inline and block-level, assuming this is one. Comments | ||
// always begin with a / character. | ||
if (ch !== '/') { | ||
error("Not a comment"); | ||
} | ||
next('/'); | ||
if (ch === '/') { | ||
inlineComment(); | ||
} else if (ch === '*') { | ||
blockComment(); | ||
} else { | ||
error("Unrecognized comment"); | ||
} | ||
}, | ||
white = function () { | ||
// Skip whitespace and comments. | ||
// Note that we're detecting comments by only a single / character. | ||
// This works since regular expressions are not valid JSON(5), but this will | ||
// break if there are other valid values that begin with a / character! | ||
while (ch) { | ||
if (ch === '/') { | ||
comment(); | ||
} else if (ch <= ' ') { | ||
next(); | ||
} else { | ||
return; | ||
} | ||
} | ||
}, | ||
word = function () { | ||
@@ -197,11 +301,28 @@ | ||
white(); | ||
if (ch === ']') { | ||
next(']'); | ||
return array; // empty array | ||
} | ||
while (ch) { | ||
array.push(value()); | ||
white(); | ||
if (ch === ']') { | ||
next(']'); | ||
return array; // Potentially empty array | ||
} | ||
// Omitted values are allowed and detected by the presence | ||
// of a trailing comma. Whether the value was omitted or | ||
// not, the current character after this block should be | ||
// the character after the value. | ||
if (ch === ',') { | ||
// Pushing an undefined value isn't quite equivalent | ||
// to what ES5 does in practice, but we can emulate it | ||
// by incrementing the array's length. | ||
array.length += 1; | ||
// Don't go next; the comma is the character after the | ||
// omitted (undefined) value. | ||
} else { | ||
array.push(value()); | ||
// The various value methods call next(); the current | ||
// character here is now the one after the value. | ||
} | ||
white(); | ||
// If there's no comma after this value, this needs to | ||
// be the end of the array. | ||
if (ch !== ',') { | ||
next(']'); | ||
return array; | ||
@@ -219,2 +340,3 @@ } | ||
// Parse an object value. | ||
// TODO Update to support unquoted keys. | ||
@@ -227,8 +349,16 @@ var key, | ||
white(); | ||
if (ch === '}') { | ||
next('}'); | ||
return object; // empty object | ||
} | ||
while (ch) { | ||
key = string(); | ||
if (ch === '}') { | ||
next('}'); | ||
return object; // Potentially empty object | ||
} | ||
// Keys can be unquoted. If they are, they need to be | ||
// valid JS identifiers. | ||
if (ch === '"' || ch === "'") { | ||
key = string(); | ||
} else { | ||
key = identifier(); | ||
} | ||
white(); | ||
@@ -241,3 +371,5 @@ next(':'); | ||
white(); | ||
if (ch === '}') { | ||
// If there's no comma after this pair, this needs to be | ||
// the end of the object. | ||
if (ch !== ',') { | ||
next('}'); | ||
@@ -265,2 +397,3 @@ return object; | ||
case '"': | ||
case "'": | ||
return string(); | ||
@@ -314,3 +447,3 @@ case '-': | ||
exports.stringify = function (obj, replacer, space) { | ||
JSON5.stringify = function (obj, replacer, space) { | ||
// Since regular JSON is a strict subset of JSON5, we'll always output as | ||
@@ -317,0 +450,0 @@ // regular JSON to foster better interoperability. TODO Should we not? |
{ "name": "json5" | ||
, "version": "0.0.1" | ||
, "description": "Modern JSON." | ||
, "version": "0.0.0" | ||
, "keywords": ["json", "json5"] | ||
, "author": "Aseem Kishore <aseem.kishore@gmail.com>" | ||
, "main": "json5" | ||
, "dependencies": {} | ||
, "devDependencies": | ||
{ "mocha": "~1.0.3" | ||
} | ||
, "scripts": | ||
{ "test": "node test" | ||
{ "test": "mocha --ui exports --reporter list" | ||
} | ||
, "homepage": "https://github.com/aseemk/json5" | ||
,"repository": | ||
{ "type" : "git" | ||
, "url" : "https://github.com/aseemk/json5.git" | ||
} | ||
} |
@@ -10,13 +10,18 @@ # JSON5 – Modern JSON | ||
JSON5 aims to do for JSON what ES5 and HTML5 did for JavaScript and HTML. | ||
It also aims to continue being a subset of regular JavaScript — ES5 flavor. | ||
JSON5 does for JSON what ES5 did for ES3. It also is to regular ES5 what JSON | ||
was to ES3 — a pure subset. | ||
This module provides a replacement for ES5's native `JSON.parse()` method that | ||
understands these additions. The parser is based directly off of Douglas | ||
Crockford's [json_parse.js][], which avoids `eval()` and validates input as it | ||
parses it, making it secure and safe to use today. | ||
## Features | ||
This project is a WIP, so these aren't necessarily all implemented yet, but | ||
these are the goals: | ||
- Object keys don't need to be quoted if they contain no special characters. | ||
Yes, even reserved keywords are valid unquoted keys in ES5. | ||
*[TODO: Unicode characters and escape sequences aren't yet supported in | ||
unquoted keys.]* | ||
- Strings can be single-quoted. | ||
@@ -30,3 +35,3 @@ | ||
- *[TODO]* Octal and hexadecimal numbers are allowed. *[Is this a bad idea?]* | ||
- *[IDEA: Allow octal and hexadecimal numbers.]* | ||
@@ -58,2 +63,48 @@ ## Example | ||
## Installation | ||
Via npm on Node: | ||
``` | ||
npm install json5 | ||
``` | ||
```js | ||
var JSON5 = require('json5'); | ||
``` | ||
Or in the browser (adds the `JSON5` object to the global namespace): | ||
```html | ||
<script src="json5.js"></script> | ||
``` | ||
## Usage | ||
```js | ||
var obj = JSON5.parse('{unquoted:"key",trailing:"comma",}'); | ||
var str = JSON5.stringify(obj); | ||
console.log(obj); | ||
console.log(str); | ||
``` | ||
`JSON5.stringify()` is currently aliased to the native `JSON.stringify()` in | ||
order for the output to be fully compatible with all JSON parsers today. | ||
## Development | ||
``` | ||
git clone git://github.com/aseemk/json5.git | ||
cd json5 | ||
npm link | ||
npm test | ||
``` | ||
Feel free to [file issues](https://github.com/aseemk/json5/issues) and submit | ||
[pull requests](https://github.com/aseemk/json5/pulls) — contributions are | ||
welcome. | ||
If you submit a pull request, please be sure to add or update corresponding | ||
test cases, and ensure that `npm test` continues to pass. | ||
## License | ||
@@ -74,4 +125,5 @@ | ||
new parser to implement these ideas this was within my reach! | ||
This code is also modeled directly off of Doug's open-source [json_parse.js]( | ||
https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js) parser. | ||
I'm super grateful for that clean and well-documented code. | ||
This code is also modeled directly off of Doug's open-source [json_parse.js][] | ||
parser. I'm super grateful for that clean and well-documented code. | ||
[json_parse.js]: https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
22853
40
409
1
126
1
1
2