{"id":13780382,"url":"https://github.com/lifthrasiir/cson","last_synced_at":"2025-07-26T02:03:46.795Z","repository":{"id":10476884,"uuid":"12653789","full_name":"lifthrasiir/cson","owner":"lifthrasiir","description":"Cursive Script Object Notation","archived":false,"fork":false,"pushed_at":"2022-04-30T17:56:30.000Z","size":9,"stargazers_count":62,"open_issues_count":2,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-14T10:43:10.466Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lifthrasiir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-09-06T20:26:16.000Z","updated_at":"2024-06-23T19:00:16.000Z","dependencies_parsed_at":"2022-07-21T16:02:20.405Z","dependency_job_id":null,"html_url":"https://github.com/lifthrasiir/cson","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lifthrasiir/cson","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifthrasiir%2Fcson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifthrasiir%2Fcson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifthrasiir%2Fcson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifthrasiir%2Fcson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lifthrasiir","download_url":"https://codeload.github.com/lifthrasiir/cson/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifthrasiir%2Fcson/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267103589,"owners_count":24036504,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-26T02:00:08.937Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T18:01:15.138Z","updated_at":"2025-07-26T02:03:46.715Z","avatar_url":"https://github.com/lifthrasiir.png","language":null,"funding_links":[],"categories":["What's Next?","Others"],"sub_categories":["CSON (I)"],"readme":"CSON\n====\n\n**CSON**(Cursive Script Object Notation) is\na strict superset of [JavaScript Object Notation][json](JSON)\nthat can be written by hand (hence the name)\nand translated to a canonical JSON.\n\n[json]: http://json.org/\n\nAmong other machine-readable semi-structured data formats,\nCSON has many benefits:\n\n* Every CSON data can be translated to JSON back and forth,\n  so you can continue using the existing library\n  that only understands JSON.\n* CSON is a strict superset of JSON,\n  so you don't have to convert existing JSON data to CSON.\n* Valid JSON fragments can be used anywhere in the CSON data,\n  unlike several configuration file formats.\n* CSON is not whitespace-sensitive\n  but still encourages writers to put the proper indentation.\n* [You can use it for evil!][crockford-on-evil]\n\n[crockford-on-evil]: https://en.wikipedia.org/wiki/Douglas_Crockford#Criticism\n\nCSON is designed by [Kang Seonghoon][kang-seonghoon].\nWhile the core principle of CSON is set in stone,\nplease note that this is not the final specification\nand details may change without a notice.\n\n[kang-seonghoon]: http://mearie.org/\n\n\nBrief Introduction\n------------------\n\nEvery JSON data is a valid CSON.\n\n~~~~\n{\"hello\": \"world\",\n \"the\": [\"answer\", \"is\", 42]}\n~~~~\n\nIn CSON you can write a line-long comment starting with `#`.\nIt can go anywhere the whitespace is expected.\n\n~~~~\n# CSON data example\n{\"hello\": \"world\", # ...and goodbye\n \"the\": [\"answer\", \"is\", 42]}\n~~~~\n\nUnlike JSON, you can use a single quoted (`'`) string as well.\n\n~~~~\n# CSON data example\n{'hello': 'world', # ...and goodbye\n 'the': ['answer', 'is', 42]}\n~~~~\n\nCommas right before the closing bracket (`]`) or the closing brace (`}`)\nare ignored for the ease of copy and paste.\n\n~~~~\n# CSON data example\n{\n'hello': 'world', # ...and goodbye\n'the': ['answer', 'is', 42],\n}\n~~~~\n\nYou can omit the comma (`,`) when followed by newline.\n\n~~~~\n# CSON data example\n{\n'hello': 'world' # ...and goodbye\n'the': ['answer', 'is'\n        42]\n}\n~~~~\n\nLikewise, the colon (`:`) can be replaced with the equal sign (`=`).\n\n~~~~\n# CSON data example\n{\n'hello' = 'world' # ...and goodbye\n'the' = ['answer', 'is'\n         42]\n}\n~~~~\n\nEscape sequences in the string work same as JSON.\nCSON provides an alternative string syntax called a **verbatim** string\nwhich starts with `|` and ends with a newline.\nNo escape sequence is processed within the verbatim string,\nso `\\n` in the following example is parsed as is.\n\n~~~~\n# CSON data example\n{\n'hello' = |world\\n  ...and goodbye\n'the' = ['answer', 'is'\n         42]\n}\n~~~~\n\nMultiple verbatim strings in a row are connected to a single string\nwith a newline (`\\n`) among them.\nYou are not required to align the starts of verbatim strings,\nbut it would be a good habit to do so.\n\n~~~~\n# CSON data example\n{\n'hello' =\n  |world\n  |  ...and goodbye\n'the' = ['answer', 'is'\n         42]\n}\n~~~~\n\nConnecting multiple verbatim strings\ntake precedence over the comma in the array.\nIf you want an array with multiple verbatim strings\nnot connected to each other,\nyou have to explicitly insert a comma (a bit ugly):\n\n~~~~\n# CSON data example\n{\n'hello' =\n  |world\n  |  ...and goodbye\n'the' = [\n  |answer\n ,|is\n ,42]\n}\n~~~~\n\nOr you may put an additional newline\nto separate verbatim strings (a bit better):\n\n~~~~\n# CSON data example\n{\n'hello' =\n  |world\n  |  ...and goodbye\n'the' = [\n  |answer\n\n  |is\n\n  42]\n}\n~~~~\n\nYou can use a bare string without quotes as the key in the object\nas long as it does not contain certain chatacters\nincluding whitespaces and CSON-special punctuations:\n\n~~~~\n# CSON data example\n{\nhello =\n  |world\n  |  ...and goodbye\nthe = ['answer', 'is'\n       42]\n}\n~~~~\n\nFinally, if the top-level data consists of the object,\nthe enclosing braces can be omitted:\n\n~~~~\n# CSON data example\nhello =\n  |world\n  |  ...and goodbye\nthe = ['answer', 'is'\n       42]\n~~~~\n\nYou can now see why CSON is so good for configuration files.\n\n\nFormal Grammar\n--------------\n\nCSON is defined as grammar additions\nto the ABNF grammar specified by [RFC 4627],\nwhich formally defines JSON.\nOther constraints of JSON, like an unique key requirement,\nequally apply to CSON.\nChanges follow:\n\n[RFC 4627]: http://tools.ietf.org/html/rfc4627\n\n~~~~\n  JSON-text = object\n            / array\n+           / ws object-items\n\n  begin-array     = ws %x5B ws    ; [ left square bracket\n  begin-object    = ws %x7B ws    ; { left curly bracket\n  end-array       = ws %x5D ws    ; ] right square bracket\n  end-object      = ws %x7D ws    ; } right curly bracket\n  name-separator  = ws %x3A ws    ; : colon\n+                 / ws %x3D ws    ; = equal sign\n  value-separator = ws %x2C ws    ; , comma\n+                 / newline ws\n\n  ws = *(\n            %x20 /                ; Space\n            %x09 /                ; Horizontal tab\n-           %x0A /                ; Line feed or New line\n-           %x0D                  ; Carriage return\n+           newline-char /\n+           comment\n        )\n+ newline = *(%x20 / %x09) newline-char\n+ newline-char = %x0A             ; Line feed or New line\n+              / %x0D             ; Carriage return\n+ comment = sharp *comment-char\n+ sharp = %x23                    ; # sharp\n+ comment-char = %x00-09 / %x0B-0C / %x0E-10FFFF\n\n  value = false / null / true / object / array / number / string\n\n  false = %x66.61.6c.73.65        ; false\n  null  = %x6e.75.6c.6c           ; null\n  true  = %x74.72.75.65           ; true\n\n- object = begin-object [ member *( value-separator member ) ] end-object\n+ object = begin-object [ object-items ] end-object\n+ object-items = member *( value-separator member ) [ value-separator ]\n- member = string name-separator value\n+ member = name name-separator value\n+ name = string / bare-string\n\n- array = begin-array [ value *( value-separator value ) ] end-array\n+ array = begin-array [ array-items ] end-array\n+ array-items = value *( value-separator value ) [ value-separator ]\n\n  number = [ minus ] int [ frac ] [ exp ]\n  decimal-point = %x2E            ; .\n  digit1-9 = %x31-39              ; 1-9\n  e = %x65 / %x45                 ; e E\n  exp = e [ minus / plus ] 1*DIGIT\n  frac = decimal-point 1*DIGIT\n  int = zero / ( digit1-9 *DIGIT )\n  minus = %x2D                    ; -\n  plus = %x2B                     ; +\n  zero = %x30                     ; 0\n\n- string = quotation-mark *char quotation-mark\n+ string = quotation-mark *dquoted-char quotation-mark\n+        / apostrophe-mark *squoted-char apostrophe-mark\n- char = unescaped /\n-        escape (\n+ dquoted-char = dquoted-unescaped / escaped\n+ squoted-char = squoted-unescaped / escaped\n+ escaped = escape (\n+            %x27 /               ; '    apostrophe      U+0027\n             %x22 /               ; \"    quotation mark  U+0022\n             %x5C /               ; \\    reverse solidus U+005C\n             %x2F /               ; /    solidus         U+002F\n             %x62 /               ; b    backspace       U+0008\n             %x66 /               ; f    form feed       U+000C\n             %x6E /               ; n    line feed       U+000A\n             %x72 /               ; r    carriage return U+000D\n             %x74 /               ; t    tab             U+0009\n             %x75 4HEXDIG )       ; uXXXX                U+XXXX\n  escape = %x5C                   ; \\\n  quotation-mark = %x22           ; \"\n+ apostrophe-mark = %x27          ; '\n- unescaped = %x20-21 / %x23-5B / %x5D-10FFFF\n+ dquoted-unescaped = %x20-21 / %x23-5B / %x5D-10FFFF\n+ squoted-unescaped = %x20-26 / %x28-5B / %x5D-10FFFF\n\n+ verbatim-string = verbatim-fragment *(newline ws verbatim-fragment)\n+ verbatim-fragment = pipe *verbatim-char\n+ pipe = %x7C                     ; |\n+ verbatim-char = %x20-10FFFF\n\n+ bare-string = id-start *id-end\n\n+ id-start = %x24 / %x2D / %x41-5A / %x5F / %x61-7A / %xAA / %xB5\n+          / %xBA / %xC0-D6 / %xD8-F6 / %xF8-02FF / %x0370-037D\n+          / %x037F-1FFF / %x200C-200D / %x2070-218F / %x2C00-2FEF\n+          / %x3001-D7FF / %xF900-FDCF / %xFDF0-FFFD / %x10000-EFFFF\n+ id-end = id-start / %x2E / %x30-39 / %xB7 / %x0300-036F / %x203F-2040\n~~~~\n\nPlease note that this grammar itself is ambiguous about\nthe sequence of nonterminals\n`verbatim-fragment`, `newline`, `ws` and `verbatim-fragment`\nin the array context (i.e. `array-items`),\nwhich can be interpreted as a single `verbatim-string`\nor a `verbatim-string` followed by `value-separator`\nand another `verbatim-string`.\nThe parser should use the former interpretation in this case.\n\n\nDesign Considerations\n---------------------\n\nCSON is designed with the following considerations in mind.\n\n### JSON Equivalence\n\nJSON has a broad language, library and tool support.\nIt is very important that CSON can be translated to JSON\nto leverage this support.\n[YAML], on the other hand, is also a strict JSON superset\nbut YAML falls short on this criterion\nas YAML cannot be readily converted to JSON.\n\n[YAML]: http://yaml.org/\n\nIt is not a strong requirement for CSON to be a JSON superset,\nbut since JSON already has important data structures (arrays and objects)\nand since many would want to write JSON fragment in the CSON data\nit was decided that CSON would be a JSON superset.\nThis also gave a benefit of simpler grammar\nand no requirement for additional types and recursive structures.\n\n### Ease of Writing\n\nCSON solves several major problems with hand-writing JSON by providing:\n\n- The ability to write comments;\n- The ability to use both single-quoted and double-quoted strings;\n- The ability to write multi-line strings in multiple lines;\n- The ability to omit quotes around the string in certain circumstances; and\n- The ability to write a redundant comma.\n\nThese problems have been frequently wanted features for JSON,\nespecially since many of them are allowed by JavaScript and ECMAScript,\non which JSON is based.\n\nAlso, since CSON is expected to be used for configuration formats,\nan equal sign `=` used by INI files can be also used in CSON.\nThis makes CSON a direct replacement for simple configuration files.\n\n### Ease of Parsing\n\nCSON is as easy to parse as JSON.\nIt has an obvious LL(1) grammar which is omitted for brevity\nand can be implemented with modifications to the existing JSON parser.\nIn practice, the hand-written recursive descent parser with a combined lexer\nwould fare better due to its simplicity.\n\nThe design of CSON explicitly avoids the context sensitivity\nby giving an unique lookahead character for different constructs,\nand also avoids the dependence to different Unicode standards\nby giving a simplified set of Unicode ranges as needed.\n(The latter will be discussed later in depth.)\n\n### Incompatibility to JavaScript\n\nCSON is *not* designed for being a JavaScript subset,\nas some features wanted for CSON are absent in JavaScript anyway.\n(For example, JavaScript does not have a multi-line string literal.)\nTherefore it was decided that\nnew features to CSON are made an invalid JavaScript if possible.\nSpecifically:\n\n- The comment syntax (`#`) is different from JavaScript's,\n  and CSON's comment will cause an unconditional error in JavaScript.\n- Same for the verbatim string syntax (`|`), albeit in the limited extent.\n  For example, `42, |foo` is an unconditional error,\n  but `42` followed by a newline and `|foo` is not.\n\nStill, unlike JSON\n(JSON with a top-level object is always an invalid JavaScript),\nCSON does not have a strong guarantee of being an invalid JavaScript.\nYou should avoid using CSON over HTTP for this reason.\n\n### No Whitespace Significance\n\nWhitespace is very prone to accidental changes,\nwhich is not desirable for the data format.\nFor example, copying and pasting the whitespace-significant data\nor expanding tabs to spaces in the editor\ncan easily lose the information from time to time.\n\nWhitespace also makes the implementation more complex.\nWhitespace-significant grammars need a special treatment for the lexer,\nand should implement all possible indent and dedent scenarios.\n(That is why YAML grammar is so horrible.)\nIt is also very hard to handle a mix of tabs and spaces;\nin fact, Python traditionally had an arbitrary assumption of\neight-space tabs (!) until Python 3.\n\nWhile CSON does not have a whitespace-significant structure,\none major feature of CSON does encourage the whitespace significance:\nmulti-line verbatim strings.\nThe prefix character for them, `|`, is intentionally chosen\nto encourage writers to align them in the same column.\n\n### No Additional Types\n\nBesides from the fact that JSON does not have them,\nadditional types brings lots of complexity in the implementations.\nAs an example,\nif we had a date and time format like [TOML]\nthen we and every implementation have to deal with the following things:\n\n- The date without the time;\n- The timezone (the UNIX timestamp would be a better option\n  if you want to force UTC);\n- The canonicalization of date and time\n  (which is essentially impossible in certain timezones);\n- Leap seconds (so you would want to force TAI instead);\n- Sub-second accuracy; and\n- Other niceties from [ISO 8601].\n\nThere is [Erik Naguum's excellent essay][lugm-time] on this subject.\n\n[TOML]: https://github.com/mojombo/toml/\n[ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601\n[lugm-time]: http://naggum.no/lugm-time.html\n\nThe truth is that,\nsuch complex constraints are not a job of data formats.\nThe complexity of data formats directly affects\nthe (much larger) complexity of supporting implementations,\ntherefore we want to keep the data formats simple.\n\nYou can always define your own standard over JSON/CSON\nfor the interchange of customized data types.\nIn fact JSON users use a reserved key like `$type` for that,\nso CSON respects this convention\nby making a key starting with `$` easier to write.\n\n### No Recursive Structure\n\nAgain, besides from the fact that JSON does not have it,\nrecursive structures are considered harmful.\n\nUnlike programming languages\n(you basically wants a Turing-completeness)\ndata formats should be limited in computational power\n(and similarly, expressiveness)\nin order to be efficiently processed.\nFor example, many configuration formats with programability\nsuffer from the inabillity of static inspection.\n\nThat said, recursive structures are not necessarily harmful.\nLISP has supported recursive structures for decades\nand even has a proper serialization and deserialization algorithm.\nBut this \"feature\" is not without a complexity;\nthe tree traversal requires a complex routine,\nand it introduces free-form identifiers independent of the actual data\nto the data formats.\nIn some cases, it even requires a temporarily mutable data structure\nwhich is definitely bad for restricting expressiveness.\n\nAs with additional types,\nthe better way is to restrict data formats and\nusing a supplementary standard like [JSPON] on top of CSON.\nThat is much better than a rule-'em-all serialization format.\n\n[JSPON]: http://www.jspon.org/\n\n### (A bit of) Internationalization\n\nThe bare string syntax of CSON requies some explanation.\nIt is basically an union of two major Unicode-aware identifier syntax:\n\n1. JavaScript (i.e. ECMAScript 5th edition) identifier syntax\n2. XML (i.e. XML 1.0 5th edition) name syntax\n\n...minus a colon (`:`), which is special to CSON.\nNotably, this repertoire allows for `$` and `-` in any position,\nso special keys like `$type` can be written without quotes.\n\nNote that almost all JavaScript identifier is an XML name:\nonly exceptions are `$`, U+00AA, U+00B5 and U+00BA.\nIt is also worthwhile that the range of an XML name is very simplified;\nit contains lots of unassigned characters or punctuations\nthat can be assumed to be letters for casual use.\n(For example, U+3002 IDEOGRAPHIC FULL STOP is actually a punctuation\nbut included in an XML name anyway.)\nThis makes matching an XML name a lot easier.\n\nBoth syntaxes are carefully designed to allow as much characters as possible\nwithout introducing any ambiguity or conflict.\nFor example, both syntaxes remains valid\nafter Unicode normalization algorithm C and D,\nso a valid CSON data also remains valid after the normalization.\n(This characteristics breaks down with canonical normalizations KC/KD though.)\nThanks to these prior arts,\nCSON is able to make both users and implementations comfortable enough.\n\n\nFrequently Asked Questions\n--------------------------\n\n### What the hell with the name?\n\nCSON is written by hand and cursive script is also written by hand.\nAnd I wanted to keep -SON suffix.\nI apologize for careless naming.\nAnd I am well aware of the existence of CoffeeScript Object Notation.\nNo, I don't intend to rename CSON.\n\n\nImplementations\n---------------\n\nWorking in progress. Known implementations:\n\n* [CSON-js](http://0xabcdef.com/CSON-js/)\n* [CSON-rust](https://github.com/lifthrasiir/cson-rust)\n* [CSON-py](https://github.com/peckpeck/CSON-py)\n* [CCSON](https://github.com/Meithal/ccson)\n\nLicense\n-------\n\nThe specification of CSON is dedicated to the public domain.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flifthrasiir%2Fcson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flifthrasiir%2Fcson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flifthrasiir%2Fcson/lists"}