Comparing version 0.2.0 to 0.4.0
@@ -6,6 +6,36 @@ ### Unreleased [[code][cNew], [diff][dNew]] | ||
These changes are sitting unreleased on the `develop` branch: | ||
- (Nothing yet.) | ||
### v0.4.0 [[code][c0.4.0], [diff][d0.4.0]] | ||
[c0.4.0]: https://github.com/aseemk/json5/tree/v0.4.0 | ||
[d0.4.0]: https://github.com/aseemk/json5/compare/v0.2.0...v0.4.0 | ||
Note that v0.3.0 was tagged, but never published to npm, so this v0.4.0 | ||
changelog entry includes v0.3.0 features. | ||
This is a massive release that adds `stringify` support, among other things. | ||
- **Major:** `JSON5.stringify()` now exists! | ||
This method is analogous to the native `JSON.stringify()`; | ||
it just avoids quoting keys where possible. | ||
See the [usage documentation](./README.md#usage) for more. | ||
([#32][]; huge thanks and props [@aeisenberg][]!) | ||
- New: `NaN` and `-NaN` are now allowed number literals. | ||
([#30][]; thanks [@rowanhill][].) | ||
- New: Duplicate object keys are now allowed; the last value is used. | ||
This is the same behavior as JSON. ([#57][]; thanks [@jordanbtucker][].) | ||
- Fix: Properly handle various whitespace and newline cases now. | ||
E.g. JSON5 now properly supports escaped CR and CRLF newlines in strings, | ||
and JSON5 now accepts the same whitespace as JSON (stricter than ES5). | ||
([#58][], [#60][], and [#63][]; thanks [@jordanbtucker][].) | ||
- New: Negative hexadecimal numbers (e.g. `-0xC8`) are allowed again. | ||
(They were disallowed in v0.2.0; see below.) | ||
It turns out they *are* valid in ES5, so JSON5 supports them now too. | ||
([#36][]; thanks [@jordanbtucker][]!) | ||
### v0.2.0 [[code][c0.2.0], [diff][d0.2.0]] | ||
@@ -24,24 +54,17 @@ | ||
[v8-hex-fix]: http://code.google.com/p/v8/issues/detail?id=2240 | ||
[#36]: https://github.com/aseemk/json5/issues/36 | ||
- **Breaking:** Trailing decimal points in decimal numbers are allowed again. | ||
- New: Trailing decimal points in decimal numbers are allowed again. | ||
(They were disallowed in v0.1.0; see below.) | ||
They're allowed by ES5, and differentiating between integers and floats may | ||
make sense on some platforms. ([#16][]; thanks [@Midar][].) | ||
[#16]: https://github.com/aseemk/json5/issues/16 | ||
- **New:** `Infinity` and `-Infinity` are now allowed number literals. | ||
- New: `Infinity` and `-Infinity` are now allowed number literals. | ||
([#30][]; thanks [@pepkin88][].) | ||
[#30]: https://github.com/aseemk/json5/issues/30 | ||
- **New:** Plus signs (`+`) in front of numbers are now allowed, since it can | ||
- New: Plus signs (`+`) in front of numbers are now allowed, since it can | ||
be helpful in some contexts to explicitly mark numbers as positive. | ||
(E.g. when a property represents changes or deltas.) | ||
- Bug fix: unescaped newlines in strings are rejected now. ([#24][]; thanks | ||
[@Midar][].) | ||
- Fix: unescaped newlines in strings are rejected now. | ||
([#24][]; thanks [@Midar][].) | ||
[#24]: https://github.com/aseemk/json5/issues/24 | ||
@@ -55,5 +78,5 @@ ### v0.1.0 [[code][c0.1.0], [diff][d0.1.0]] | ||
- Support hexadecimal numbers. (Thanks [@MaxNanasy][].) | ||
- New: Support hexadecimal numbers. (Thanks [@MaxNanasy][].) | ||
- Reject octal numbers properly now. Previously, they were accepted but | ||
- Fix: Reject octal numbers properly now. Previously, they were accepted but | ||
improperly parsed as base-10 numbers. (Thanks [@MaxNanasy][].) | ||
@@ -65,3 +88,4 @@ | ||
- Support leading decimal points in decimal numbers. (Thanks [@MaxNanasy][].) | ||
- New: Support leading decimal points in decimal numbers. | ||
(Thanks [@MaxNanasy][].) | ||
@@ -74,8 +98,9 @@ - **Breaking:** Reject trailing decimal points in decimal numbers now. These | ||
- Throw proper `SyntaxError` instances on errors now. | ||
- Fix: Throw proper `SyntaxError` instances on errors now. | ||
- Add Node.js `require()` hook. Require `json5/lib/require` to register it. | ||
- New: Add Node.js `require()` hook. Register via `json5/lib/require`. | ||
- Add Node.js executable to compile JSON5 files to JSON. Run with `json5`. | ||
- New: Add Node.js `json5` executable to compile JSON5 files to JSON. | ||
### v0.0.1 [[code][c0.0.1], [diff][d0.0.1]] | ||
@@ -99,2 +124,3 @@ | ||
### v0.0.0 [[code](https://github.com/aseemk/json5/tree/v0.0.0)] | ||
@@ -105,3 +131,5 @@ | ||
[json_parse.js]: https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js | ||
[v8-hex-fix]: http://code.google.com/p/v8/issues/detail?id=2240 | ||
@@ -111,1 +139,14 @@ [@MaxNanasy]: https://github.com/MaxNanasy | ||
[@pepkin88]: https://github.com/pepkin88 | ||
[@rowanhill]: https://github.com/rowanhill | ||
[@aeisenberg]: https://github.com/aeisenberg | ||
[@jordanbtucker]: https://github.com/jordanbtucker | ||
[#16]: https://github.com/aseemk/json5/issues/16 | ||
[#24]: https://github.com/aseemk/json5/issues/24 | ||
[#30]: https://github.com/aseemk/json5/issues/30 | ||
[#32]: https://github.com/aseemk/json5/issues/32 | ||
[#36]: https://github.com/aseemk/json5/issues/36 | ||
[#57]: https://github.com/aseemk/json5/issues/57 | ||
[#58]: https://github.com/aseemk/json5/pull/58 | ||
[#60]: https://github.com/aseemk/json5/pull/60 | ||
[#63]: https://github.com/aseemk/json5/pull/63 |
297
lib/json5.js
@@ -34,2 +34,12 @@ // json5.js | ||
}, | ||
ws = [ | ||
' ', | ||
'\t', | ||
'\r', | ||
'\n', | ||
'\v', | ||
'\f', | ||
'\xA0', | ||
'\uFEFF' | ||
], | ||
text, | ||
@@ -64,2 +74,10 @@ | ||
peek = function () { | ||
// Get the next character without consuming it or | ||
// assigning it to the ch varaible. | ||
return text.charAt(at); | ||
}, | ||
identifier = function () { | ||
@@ -106,3 +124,3 @@ | ||
if (ch === '-' || ch === '+') { | ||
sign = string = ch; | ||
sign = ch; | ||
next(ch); | ||
@@ -120,2 +138,12 @@ } | ||
// support for NaN | ||
if (ch === 'N' ) { | ||
number = word(); | ||
if (!isNaN(number)) { | ||
error('expected word to be NaN'); | ||
} | ||
// ignore sign as -NaN also is NaN | ||
return number; | ||
} | ||
if (ch === '0') { | ||
@@ -133,7 +161,2 @@ string += ch; | ||
// https://github.com/aseemk/json5/issues/36 | ||
if (base === 16 && sign) { | ||
error('Signed hexadecimal literal'); | ||
} | ||
switch (base) { | ||
@@ -171,3 +194,9 @@ case 10: | ||
} | ||
number = +string; | ||
if(sign === '-') { | ||
number = -string; | ||
} else { | ||
number = +string; | ||
} | ||
if (!isFinite(number)) { | ||
@@ -210,2 +239,6 @@ error("Bad number"); | ||
string += String.fromCharCode(uffff); | ||
} else if (ch === '\r') { | ||
if (peek() === '\n') { | ||
next(); | ||
} | ||
} else if (typeof escapee[ch] === 'string') { | ||
@@ -242,4 +275,4 @@ string += escapee[ch]; | ||
next(); | ||
if (ch === '\n') { | ||
next('\n'); | ||
if (ch === '\n' || ch === '\r') { | ||
next(); | ||
return; | ||
@@ -305,3 +338,3 @@ } | ||
comment(); | ||
} else if (ch <= ' ') { | ||
} else if (ws.indexOf(ch) >= 0) { | ||
next(); | ||
@@ -348,2 +381,7 @@ } else { | ||
return Infinity; | ||
case 'N': | ||
next( 'N' ); | ||
next( 'a' ); | ||
next( 'N' ); | ||
return NaN; | ||
} | ||
@@ -416,5 +454,2 @@ error("Unexpected '" + ch + "'"); | ||
next(':'); | ||
if (Object.hasOwnProperty.call(object, key)) { | ||
error('Duplicate key "' + key + '"'); | ||
} | ||
object[key] = value(); | ||
@@ -464,3 +499,3 @@ white(); | ||
text = source; | ||
text = String(source); | ||
at = 0; | ||
@@ -499,6 +534,234 @@ ch = ' '; | ||
// JSON5 stringify will not quote keys where appropriate | ||
JSON5.stringify = function (obj, replacer, space) { | ||
// Since regular JSON is a strict subset of JSON5, we'll always output | ||
// regular JSON to foster better interoperability. TODO Should we not? | ||
return JSON.stringify.apply(JSON, arguments); | ||
if (replacer && (typeof(replacer) !== "function" && !isArray(replacer))) { | ||
throw new Error('Replacer must be a function or an array'); | ||
} | ||
var getReplacedValueOrUndefined = function(holder, key, isTopLevel) { | ||
var value = holder[key]; | ||
// Replace the value with its toJSON value first, if possible | ||
if (value && value.toJSON && typeof value.toJSON === "function") { | ||
value = value.toJSON(); | ||
} | ||
// If the user-supplied replacer if a function, call it. If it's an array, check objects' string keys for | ||
// presence in the array (removing the key/value pair from the resulting JSON if the key is missing). | ||
if (typeof(replacer) === "function") { | ||
return replacer.call(holder, key, value); | ||
} else if(replacer) { | ||
if (isTopLevel || isArray(holder) || replacer.indexOf(key) >= 0) { | ||
return value; | ||
} else { | ||
return undefined; | ||
} | ||
} else { | ||
return value; | ||
} | ||
}; | ||
function isWordChar(char) { | ||
return (char >= 'a' && char <= 'z') || | ||
(char >= 'A' && char <= 'Z') || | ||
(char >= '0' && char <= '9') || | ||
char === '_' || char === '$'; | ||
} | ||
function isWordStart(char) { | ||
return (char >= 'a' && char <= 'z') || | ||
(char >= 'A' && char <= 'Z') || | ||
char === '_' || char === '$'; | ||
} | ||
function isWord(key) { | ||
if (typeof key !== 'string') { | ||
return false; | ||
} | ||
if (!isWordStart(key[0])) { | ||
return false; | ||
} | ||
var i = 1, length = key.length; | ||
while (i < length) { | ||
if (!isWordChar(key[i])) { | ||
return false; | ||
} | ||
i++; | ||
} | ||
return true; | ||
} | ||
// export for use in tests | ||
JSON5.isWord = isWord; | ||
// polyfills | ||
function isArray(obj) { | ||
if (Array.isArray) { | ||
return Array.isArray(obj); | ||
} else { | ||
return Object.prototype.toString.call(obj) === '[object Array]'; | ||
} | ||
} | ||
function isDate(obj) { | ||
return Object.prototype.toString.call(obj) === '[object Date]'; | ||
} | ||
isNaN = isNaN || function(val) { | ||
return typeof val === 'number' && val !== val; | ||
}; | ||
var objStack = []; | ||
function checkForCircular(obj) { | ||
for (var i = 0; i < objStack.length; i++) { | ||
if (objStack[i] === obj) { | ||
throw new TypeError("Converting circular structure to JSON"); | ||
} | ||
} | ||
} | ||
function makeIndent(str, num, noNewLine) { | ||
if (!str) { | ||
return ""; | ||
} | ||
// indentation no more than 10 chars | ||
if (str.length > 10) { | ||
str = str.substring(0, 10); | ||
} | ||
var indent = noNewLine ? "" : "\n"; | ||
for (var i = 0; i < num; i++) { | ||
indent += str; | ||
} | ||
return indent; | ||
} | ||
var indentStr; | ||
if (space) { | ||
if (typeof space === "string") { | ||
indentStr = space; | ||
} else if (typeof space === "number" && space >= 0) { | ||
indentStr = makeIndent(" ", space, true); | ||
} else { | ||
// ignore space parameter | ||
} | ||
} | ||
// Copied from Crokford's implementation of JSON | ||
// See https://github.com/douglascrockford/JSON-js/blob/e39db4b7e6249f04a195e7dd0840e610cc9e941e/json2.js#L195 | ||
// Begin | ||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, | ||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, | ||
meta = { // table of character substitutions | ||
'\b': '\\b', | ||
'\t': '\\t', | ||
'\n': '\\n', | ||
'\f': '\\f', | ||
'\r': '\\r', | ||
'"' : '\\"', | ||
'\\': '\\\\' | ||
}; | ||
function escapeString(string) { | ||
// If the string contains no control characters, no quote characters, and no | ||
// backslash characters, then we can safely slap some quotes around it. | ||
// Otherwise we must also replace the offending characters with safe escape | ||
// sequences. | ||
escapable.lastIndex = 0; | ||
return escapable.test(string) ? '"' + string.replace(escapable, function (a) { | ||
var c = meta[a]; | ||
return typeof c === 'string' ? | ||
c : | ||
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); | ||
}) + '"' : '"' + string + '"'; | ||
} | ||
// End | ||
function internalStringify(holder, key, isTopLevel) { | ||
var buffer, res; | ||
// Replace the value, if necessary | ||
var obj_part = getReplacedValueOrUndefined(holder, key, isTopLevel); | ||
if (obj_part && !isDate(obj_part)) { | ||
// unbox objects | ||
// don't unbox dates, since will turn it into number | ||
obj_part = obj_part.valueOf(); | ||
} | ||
switch(typeof obj_part) { | ||
case "boolean": | ||
return obj_part.toString(); | ||
case "number": | ||
if (isNaN(obj_part) || !isFinite(obj_part)) { | ||
return "null"; | ||
} | ||
return obj_part.toString(); | ||
case "string": | ||
return escapeString(obj_part.toString()); | ||
case "object": | ||
if (obj_part === null) { | ||
return "null"; | ||
} else if (isArray(obj_part)) { | ||
checkForCircular(obj_part); | ||
buffer = "["; | ||
objStack.push(obj_part); | ||
for (var i = 0; i < obj_part.length; i++) { | ||
res = internalStringify(obj_part, i, false); | ||
buffer += makeIndent(indentStr, objStack.length); | ||
if (res === null || typeof res === "undefined") { | ||
buffer += "null"; | ||
} else { | ||
buffer += res; | ||
} | ||
if (i < obj_part.length-1) { | ||
buffer += ","; | ||
} else if (indentStr) { | ||
buffer += "\n"; | ||
} | ||
} | ||
objStack.pop(); | ||
buffer += makeIndent(indentStr, objStack.length, true) + "]"; | ||
} else { | ||
checkForCircular(obj_part); | ||
buffer = "{"; | ||
var nonEmpty = false; | ||
objStack.push(obj_part); | ||
for (var prop in obj_part) { | ||
if (obj_part.hasOwnProperty(prop)) { | ||
var value = internalStringify(obj_part, prop, false); | ||
isTopLevel = false; | ||
if (typeof value !== "undefined" && value !== null) { | ||
buffer += makeIndent(indentStr, objStack.length); | ||
nonEmpty = true; | ||
var key = isWord(prop) ? prop : escapeString(prop); | ||
buffer += key + ":" + (indentStr ? ' ' : '') + value + ","; | ||
} | ||
} | ||
} | ||
objStack.pop(); | ||
if (nonEmpty) { | ||
buffer = buffer.substring(0, buffer.length-1) + makeIndent(indentStr, objStack.length) + "}"; | ||
} else { | ||
buffer = '{}'; | ||
} | ||
} | ||
return buffer; | ||
default: | ||
// functions and undefined should be ignored | ||
return undefined; | ||
} | ||
} | ||
// special case...when undefined is used inside of | ||
// a compound object/array, return null. | ||
// but when top-level, return undefined | ||
var topLevelHolder = {"":obj}; | ||
if (obj === undefined) { | ||
return getReplacedValueOrUndefined(topLevelHolder, '', true); | ||
} | ||
return internalStringify(topLevelHolder, '', true); | ||
}; |
{ | ||
"name": "json5", | ||
"version": "0.2.0", | ||
"version": "0.4.0", | ||
"description": "JSON for the ES5 era.", | ||
@@ -10,4 +10,6 @@ "keywords": [ | ||
"author": "Aseem Kishore <aseem.kishore@gmail.com>", | ||
"license": "MIT", | ||
"contributors": [ | ||
"Max Nanasy <max.nanasy@gmail.com>" | ||
"Max Nanasy <max.nanasy@gmail.com>", | ||
"Andrew Eisenberg <andrew@eisenberg.as>" | ||
], | ||
@@ -14,0 +16,0 @@ "main": "lib/json5.js", |
163
README.md
[![Build Status](https://travis-ci.org/aseemk/json5.png)](https://travis-ci.org/aseemk/json5) | ||
# JSON5 – Modern JSON | ||
JSON isn't the friendliest to write and maintain by hand. Keys need to be | ||
quoted; objects and arrays can't have trailing commas; comments aren't | ||
supported — even though none of these are the case with regular JavaScript | ||
today. | ||
JSON is an excellent data format, but we think it can be better. | ||
Restricting JSON to such a strict subset of "JavaScript object notation" made | ||
sense for making it a great data-exchange format, but JSON's usage has | ||
expanded [beyond][ex1] [machine-to-machine][ex2] [communication][ex3]. | ||
**JSON5 is a proposed extension to JSON** that aims to make it easier for | ||
*humans to write and maintain* by hand. It does this by adding some minimal | ||
syntax features directly from ECMAScript 5. | ||
JSON5 remains a **strict subset of JavaScript**, adds **no new data types**, | ||
and **works with all existing JSON content**. | ||
JSON5 is *not* an official successor to JSON, and JSON5 content may *not* | ||
work with existing JSON parsers. For this reason, JSON5 files use a new .json5 | ||
extension. *(TODO: new MIME type needed too.)* | ||
The code here is a **reference JavaScript implementation** for both Node.js | ||
and all browsers. It's based directly off of Douglas Crockford's own [JSON | ||
implementation][json_parse.js], and it's both robust and secure. | ||
## Why | ||
JSON isn't the friendliest to *write*. Keys need to be quoted, objects and | ||
arrays can't have trailing commas, and comments aren't allowed — even though | ||
none of these are the case with regular JavaScript today. | ||
That was fine when JSON's goal was to be a great data format, but JSON's usage | ||
has expanded beyond *machines*. JSON is now used for writing [configs][ex1], | ||
[manifests][ex2], even [tests][ex3] — all by *humans*. | ||
[ex1]: http://plovr.com/docs.html | ||
@@ -18,27 +38,25 @@ [ex2]: http://npmjs.org/doc/json.html | ||
**JSON5 is a proposed extension to JSON** that brings ES5 enhancements to its | ||
syntax. It remains a **strict subset of JavaScript**, adds **no new data | ||
types**, and is a **strict superset of existing JSON**. | ||
There are other formats that are human-friendlier, like YAML, but changing | ||
from JSON to a completely different format is undesirable in many cases. | ||
JSON5’s aim is to remain close to JSON and JavaScript. | ||
JSON5 is not an official successor to JSON, and existing JSON parsers may not | ||
understand these new features. It's thus recommended that files use a new | ||
extension like `.json5` to be explicit. *[TODO: New MIME type too?]* | ||
This module provides a JavaScript implementation that works on all modern JS | ||
engines (even IE6). Its parser is based directly off of Douglas Crockford's | ||
eval-free [json_parse.js][], making it both secure and robust. Give it a try! | ||
## Features | ||
These are the new features of JSON5's syntax. **All of these are optional**, | ||
and **all of these are part of ES5 JavaScript**. | ||
The following is the exact list of additions to JSON's syntax introduced by | ||
JSON5. **All of these are optional**, and **all of these come from ES5**. | ||
### Objects | ||
- Object keys can be unquoted if they're valid [identifiers]( | ||
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Variables). Yes, even reserved keywords are valid unquoted keys in ES5 [[§11.1.5](http://es5.github.com/#x11.1.5), [§7.6](http://es5.github.com/#x7.6)]. | ||
*[TODO: Unicode characters and escape sequences aren't yet supported in this implementation.]* | ||
- Object keys can be unquoted if they're valid [identifiers][mdn_variables]. | ||
Yes, even reserved keywords (like `default`) are valid unquoted keys in ES5 | ||
[[§11.1.5](http://es5.github.com/#x11.1.5), [§7.6](http://es5.github.com/#x7.6)]. | ||
*(TODO: Unicode characters and escape sequences aren’t yet supported in this | ||
implementation.)* | ||
- Objects can have trailing commas. | ||
[mdn_variables]: https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Variables | ||
### Arrays | ||
@@ -57,4 +75,4 @@ | ||
- Numbers can be hexadecimal (base 16). (Note that signed hexadecimals are not | ||
allowed by ES5, nor are hexadecimal floats.) | ||
- Numbers can be hexadecimal (base 16). (But note that neither signed | ||
hexadecimals nor hexadecimal floats are allowed by ES5.) | ||
@@ -65,3 +83,3 @@ - Numbers can begin or end with a (leading or trailing) decimal point. | ||
- Numbers can begin with an explicit plus (`+`) sign. | ||
- Numbers can begin with an explicit plus sign. | ||
@@ -72,4 +90,7 @@ ### Comments | ||
## Example | ||
The following is a contrived example, but it illustrates most of the features: | ||
```js | ||
@@ -103,7 +124,58 @@ { | ||
## Installation | ||
This implementation's own [package.json5](package.json5) is more realistic: | ||
Via npm on Node: | ||
```js | ||
// This file is written in JSON5 syntax, naturally, but npm needs a regular | ||
// JSON file, so compile via `npm run build`. Be sure to keep both in sync! | ||
{ | ||
name: 'json5', | ||
version: '0.2.0', | ||
description: 'JSON for the ES5 era.', | ||
keywords: ['json', 'es5'], | ||
author: 'Aseem Kishore <aseem.kishore@gmail.com>', | ||
contributors: [ | ||
'Max Nanasy <max.nanasy@gmail.com>', | ||
], | ||
main: 'lib/json5.js', | ||
bin: 'lib/cli.js', | ||
dependencies: {}, | ||
devDependencies: { | ||
mocha: '~1.0.3', | ||
}, | ||
scripts: { | ||
build: './lib/cli.js -c package.json5', | ||
test: 'mocha --ui exports --reporter spec', | ||
}, | ||
homepage: 'http://json5.org/', | ||
repository: { | ||
type: 'git', | ||
url: 'https://github.com/aseemk/json5.git', | ||
}, | ||
} | ||
``` | ||
## Community | ||
Join the [Google Group](http://groups.google.com/group/json5) if you're | ||
interested in JSON5 news, updates, and general discussion. | ||
Don't worry, it's very low-traffic. | ||
The [GitHub wiki](https://github.com/aseemk/json5/wiki) is a good place to track | ||
JSON5 support and usage. Contribute freely there! | ||
[GitHub Issues](https://github.com/aseemk/json5/issues) is the place to | ||
formally propose feature requests and report bugs. Questions and general | ||
feedback are better directed at the Google Group. | ||
## Usage | ||
This JavaScript implementation of JSON5 simply provides a `JSON5` object just | ||
like the native ES5 `JSON` object. | ||
To use from Node: | ||
``` | ||
npm install json5 | ||
@@ -116,9 +188,9 @@ ``` | ||
Or in the browser (adds the `JSON5` object to the global namespace): | ||
To use in the browser (adds the `JSON5` object to the global namespace): | ||
```html | ||
``` | ||
<script src="json5.js"></script> | ||
``` | ||
## Usage | ||
Then in both cases, you can simply replace native `JSON` calls with `JSON5`: | ||
@@ -130,8 +202,20 @@ ```js | ||
`JSON5.stringify()` is currently aliased to the native `JSON.stringify()` in | ||
order for the output to be fully compatible with all JSON parsers today. | ||
`JSON5.parse` supports all of the JSON5 features listed above (*TODO: except | ||
Unicode*), as well as the native [`reviver` argument][json-parse]. | ||
If you're running Node, you can also register a JSON5 `require()` hook to let | ||
you `require()` `.json5` files just like you can `.json` files: | ||
[json-parse]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse | ||
`JSON5.stringify` mainly avoids quoting keys where possible, but we hope to | ||
keep expanding it in the future (e.g. to also output trailing commas). | ||
It supports the native [`replacer` and `space` arguments][json-stringify], | ||
as well. *(TODO: Any implemented `toJSON` methods aren't used today.)* | ||
[json-stringify]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify | ||
### Extras | ||
If you're running this on Node, you can also register a JSON5 `require()` hook | ||
to let you `require()` `.json5` files just like you can `.json` files: | ||
```js | ||
@@ -144,3 +228,3 @@ require('json5/lib/require'); | ||
This module also provides a `json5` executable (requires Node) for converting | ||
JSON5 files to sibling JSON files: | ||
JSON5 files to JSON: | ||
@@ -151,2 +235,3 @@ ``` | ||
## Development | ||
@@ -166,5 +251,6 @@ | ||
[pull requests](https://github.com/aseemk/json5/pulls) — contributions are | ||
welcome. If you do submit a pull request, please be sure to add or update | ||
corresponding test cases, and ensure that `npm test` continues to pass. | ||
welcome. If you do submit a pull request, please be sure to add or update the | ||
tests, and ensure that `npm test` continues to pass. | ||
## License | ||
@@ -175,2 +261,3 @@ | ||
## Credits | ||
@@ -194,1 +281,3 @@ | ||
supporter, contributing multiple patches and ideas. Thanks Max! | ||
[Andrew Eisenberg](https://github.com/aeisenberg) has contributed the `stringify` method. |
@@ -48,4 +48,11 @@ // parse.js | ||
'Test case bug: expected JSON parsing to fail.'); | ||
assert.deepEqual(parseJSON5(), parseES5(), | ||
// Need special case for NaN as NaN != NaN | ||
if ( fileName === 'nan.json5' ) { | ||
assert.equal( isNaN( parseJSON5() ), isNaN( parseES5() ), | ||
'Expected parsed JSON5 to equal parsed ES5.'); | ||
} | ||
else { | ||
assert.deepEqual( parseJSON5(), parseES5(), | ||
'Expected parsed JSON5 to equal parsed ES5.'); | ||
} | ||
break; | ||
@@ -52,0 +59,0 @@ case '.js': |
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
No License Found
License(Experimental) License information could not be found.
Found 1 instance in 1 package
69300
141
0
1284
272