{"id":999,"date":"2022-02-01T02:04:00","date_gmt":"2022-02-01T07:04:00","guid":{"rendered":"https:\/\/www.brunerd.com\/blog\/?p=999"},"modified":"2022-02-01T02:04:02","modified_gmt":"2022-02-01T07:04:02","slug":"jpt-1-0-and-json5-rehab","status":"publish","type":"post","link":"https:\/\/www.brunerd.com\/blog\/2022\/02\/01\/jpt-1-0-and-json5-rehab\/","title":{"rendered":"jpt 1.0 and JSON5 rehab"},"content":{"rendered":"\n<p><a rel=\"noreferrer noopener\" href=\"http:\/\/json5.org\" target=\"_blank\">JSON5<\/a> <em>is not<\/em> JSON nor is an IETF standard but jpt 1.0 can rehabilitate it back to standards compliant JSON. Let&#8217;s take the example from its web page.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \/\/ comments\n  unquoted: 'and you can quote me on that',\n  singleQuotes: 'I can use \"double quotes\" here',\n  lineBreaks: \"Look, Mom! \\\nNo \\\\n's!\",\n  hexadecimal: 0xdecaf,\n  leadingDecimalPoint: .8675309, andTrailing: 8675309.,\n  positiveSign: +1,\n  trailingComma: 'in objects', andIn: &#91;'arrays',],\n  \"backwardsCompatible\": \"with JSON\",\n}<\/code><\/pre>\n\n\n\n<p>Now let&#8217;s send it through jpt<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>% jpt json5_example.txt        \n{\n  \"unquoted\": \"and you can quote me on that\",\n  \"singleQuotes\": \"I can use \\\"double quotes\\\" here\",\n  \"lineBreaks\": \"Look, Mom! No \\\\n's!\",\n  \"hexadecimal\": 912559,\n  \"leadingDecimalPoint\": 0.8675309,\n  \"andTrailing\": 8675309,\n  \"positiveSign\": 1,\n  \"trailingComma\": \"in objects\",\n  \"andIn\": &#91;\n    \"arrays\"\n  ],\n  \"backwardsCompatible\": \"with JSON\"\n}\n<\/code><\/pre>\n\n\n\n<p>That last line is a bit misleading. JSON5 texts are totally <em>not<\/em> backward compatible with JSON parsers. What they mean is that JSON5 <em>parsers<\/em> are backward compatible with JSON. FYI &#8211; Every single JSON5 addition is not compatible with JSON, I should know I had to write parsing rules and behaviors to deal with it! Let&#8217;s use the <code>-c<\/code> flag to comment on all the work that went into un-junking the above example<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>% jpt -c .\/json5_example.txt \n{\n  \"unquoted\": \"and you can quote me on that\",\n  \"singleQuotes\": \"I can use \\\"double quotes\\\" here\",\n  \"lineBreaks\": \"Look, Mom! No \\\\n's!\",\n  \"hexadecimal\": 912559,\n  \"leadingDecimalPoint\": 0.8675309,\n  \"andTrailing\": 8675309,\n  \"positiveSign\": 1,\n  \"trailingComma\": \"in objects\",\n  \"andIn\": &#91;\n    \"arrays\"\n  ],\n  \"backwardsCompatible\": \"with JSON\"\n}\n--&gt; Original error: SyntaxError: JSON Parse error: Unrecognized token '\/'\n--&gt; Byte 5: \/\/ line comment (JSON5)\n--&gt; Byte 19: unquoted object key name (JSON5)\n--&gt; Byte 29: single quoted string (JSON5)\n--&gt; Byte 63: unquoted object key name (JSON5)\n--&gt; Byte 77: single quoted string (JSON5)\n--&gt; Byte 113: unquoted object key name (JSON5)\n--&gt; Byte 138: \\ escaped newline in string (JSON5)\n--&gt; Byte 153: unquoted object key name (JSON5)\n--&gt; Byte 164: 0x hex value (JSON5)\n--&gt; Byte 177: unquoted object key name (JSON5)\n--&gt; Byte 198: decimal point wihtout preceding digit (JSON5)\n--&gt; Byte 208: unquoted object key name (JSON5)\n--&gt; Byte 228: trailing decimal lacking mantissa (JSON5)\n--&gt; Byte 233: unquoted object key name (JSON5)\n--&gt; Byte 247: explicit plus + for value (JSON5)\n--&gt; Byte 253: unquoted object key name (JSON5)\n--&gt; Byte 268: single quoted string (JSON5)\n--&gt; Byte 282: unquoted object key name (JSON5)\n--&gt; Byte 290: single quoted string (JSON5)\n--&gt; Byte 296: trailing comma (JSON5)\n--&gt; Byte 336: trailing comma (JSON5)\n<\/code><\/pre>\n\n\n\n<p>Yeah there&#8217;s so much wrong with JSON5 vs JSON its not funny. It&#8217;s baffling that Apple is acknowledging it by <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.apple.com\/documentation\/foundation\/nsjsonreadingoptions\/nsjsonreadingjson5allowed\" target=\"_blank\">adding JSON5 parsing to their frameworks<\/a>! At least they don&#8217;t generate it! Despite not being funny, let&#8217;s try anyway, here&#8217;s some more JSON5 example to show some of the other ways it can lead you astray.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n\t\"jpt_lineBreakHandling\": \"Extended parsing to ignore tabs \\\n\tafter escaped newlines.\\nIf JSON5 is supposed to be human readable \\\n\tshouldn't tabs be included in the escaping?\",\n\t\"leadingDecimalPoint\": .8675309, \n\t\"andTrailingDecimal\": 8675309.,\n\t\"negativeLeadingDecimalPoint\": -.1234, \n\n\t\/\/Infinity converts to null, use -I for string\n\t\"+Infinity\": +Infinity,\n\t\"-Infinity\": -Infinity,\n\t\"Infinity\": Infinity,\n\t\/\/null is not a number now is it? done.\n\t\"NaN\": NaN,\n}<\/code><\/pre>\n\n\n\n<p>Running this through jpt we&#8217;ll get pure JSON output<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>% jpt .\/json5_examples_brunerd.txt \n{\n  \"jpt_lineBreakHandling\": \"Extended parsing to ignore tabs after escaped newlines.\\nIf JSON5 is supposed to be human readable shouldn't tabs be included in the escaping?\",\n  \"leadingDecimalPoint\": 0.8675309,\n  \"andTrailingDecimal\": 8675309,\n  \"negativeLeadingDecimalPoint\": -0.1234,\n  \"+Infinity\": null,\n  \"-Infinity\": null,\n  \"Infinity\": null,\n  \"NaN\": null\n}\n\n\n#-I to convert to signed Infinity strings instead of null\n#-8 to convert NaN to string \"NaN\" (-N was taken, like NaN 8 is like Infinity but not quite :)\n% jpt -I8 .\/json5_examples_brunerd.txt \n{\n  \"jpt_lineBreakHandling\": \"Extended parsing to ignore tabs after escaped newlines.\\nIf JSON5 is supposed to be human readable shouldn't tabs be included in the escaping?\",\n  \"leadingDecimalPoint\": 0.8675309,\n  \"andTrailingDecimal\": 8675309,\n  \"negativeLeadingDecimalPoint\": -0.1234,\n  \"+Infinity\": \"+Infinity\",\n  \"-Infinity\": \"-Infinity\",\n  \"Infinity\": \"Infinity\",\n  \"NaN\": \"NaN\"\n}<\/code><\/pre>\n\n\n\n<p>The fact that they added the data type of +\/- Infinity and NaN really complicates the conversion since JSON doesn&#8217;t have equivalents. By default Infinity converts to <code>null<\/code> but <code>-I<\/code> will convert it to the string <code>\"Infinity\"<\/code> with signedness if specified. <code>NaN<\/code> is also converted to null by default but the <code>-8<\/code> flag will convert it to the string <code>\"NaN\"<\/code>. Why 8? Because it&#8217;s sort like infinity but it&#8217;s not, just like NaN.<\/p>\n\n\n\n<p>If you have need to rehab JSON5 back to JSON then <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/brunerd\/jpt\" target=\"_blank\">jpt<\/a> might be able to help you out. It can run on Mac all the way back to OS X Tiger (10.4) all the way up to the newest macOS Monterey (12) and on other *nixes with <code>jsc<\/code> installed. Check the <a href=\"https:\/\/github.com\/brunerd\/jpt\/releases\" target=\"_blank\" rel=\"noreferrer noopener\">jpt Releases<\/a> page<\/p>\n","protected":false},"excerpt":{"rendered":"<p>JSON5 is not JSON nor is an IETF standard but jpt 1.0 can rehabilitate it back to standards compliant JSON. Let&#8217;s take the example from its web page. Now let&#8217;s send it through jpt That last line is a bit misleading. JSON5 texts are totally not backward compatible with JSON parsers. What they mean is [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[37,51],"tags":[],"class_list":["post-999","post","type-post","status-publish","format-standard","hentry","category-jpt","category-json"],"_links":{"self":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/999","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/comments?post=999"}],"version-history":[{"count":12,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/999\/revisions"}],"predecessor-version":[{"id":1070,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/999\/revisions\/1070"}],"wp:attachment":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/media?parent=999"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/categories?post=999"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/tags?post=999"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}