User Rating 0.0 โ˜…โ˜…โ˜…โ˜…โ˜…
Total Usage 0 times
CSON Input
JSON Output
Ready
Is this tool helpful?

Your feedback helps us improve.

โ˜… โ˜… โ˜… โ˜… โ˜…

About

CSON (CoffeeScript Object Notation) removes the syntactic noise of JSON: no mandatory quotes on keys, no commas, no braces for top-level objects, and comments via #. The tradeoff is ambiguity. A misplaced indent shifts an entire subtree into the wrong parent, and most JSON validators reject CSON outright. This converter implements a recursive descent parser that resolves indentation into explicit nesting, strips comments, normalizes literals (TRUE โ†’ true, yes โ†’ true), and emits spec-compliant JSON per RFC 8259. It does not evaluate CoffeeScript expressions inside interpolated strings (#{expr}); those are preserved as literal text.

Incorrect manual conversion often produces invalid JSON that silently breaks CI pipelines, package configs, or API payloads. Common failure modes include trailing commas, unescaped control characters inside heredoc strings ('''), and numeric keys mistakenly left unquoted. This tool handles those edge cases. Note: the parser assumes well-formed CSON. Deeply malformed input with mixed tabs and spaces at inconsistent levels will produce a parse error rather than a guess.

cson json converter coffeescript object notation data format configuration

Formulas

CSON parsing follows a deterministic grammar. The converter implements a line-by-line preprocessor followed by a recursive descent parser. The core logic resolves indentation into explicit structure:

indent_level(line) = count(leading whitespace) รท base_indent

Where base_indent is auto-detected from the first indented line (typically 2 or 4 spaces, or 1 tab). Each increase in indent_level opens a new object or array scope. Each decrease closes scopes until the level matches.

The parser classifies each non-empty, non-comment line into one of three categories:

{
Key-Value pair if line matches key: valueArray element if line is a bare value at same indentContinuation if line is deeper indent with no key

Literal resolution uses pattern matching: true, yes, on โ†’ true; false, no, off โ†’ false; null, undefined โ†’ null. Numeric strings are tested against the pattern regex: /^[+-]?(0x[\da-f]+|0o[0-7]+|0b[01]+|\d+\.?\d*([eE][+-]?\d+)?)$/i. Everything else is treated as an unquoted string or, if it contains a colon after the first word, a key-value pair.

Reference Data

CSON FeatureSyntax ExampleJSON EquivalentNotes
Unquoted keyname: "Alice""name": "Alice"Keys auto-quoted in output
Single-quoted string"hello""hello"No escape processing in CSON singles
Comment# this is ignored(removed)Only line comments, no block comments
Boolean yes/noyestrueAlso accepts on/off
Boolean true/falsetruetrueCase-sensitive
Null literalnullnullAlso accepts undefined โ†’ null
Integer4242Preserved as number type
Hex number0xFF255Converted to decimal
Float3.143.14Scientific notation supported: 1e10
Implicit object (indent)person:
age: 30
{"person":{"age":30}}Indentation determines nesting
Inline object{a: 1, b: 2}{"a":1,"b":2}Braces make it explicit
Inline array[1, 2, 3][1,2,3]Standard bracket syntax
Heredoc string (single)'''
multi
line
'''
"multi\nline"Preserves newlines, no escaping
Heredoc string (double)"""
multi
line
"""
"multi\nline"Escape sequences processed
Multiline array (indent)items:
"a"
"b"
"items":["a","b"]Implicit array from bare values
Trailing comma{a: 1,}{"a":1}Tolerated and stripped
String interpolation"Hello #{name}""Hello #{name}"Not evaluated, kept as literal
InfinityInfinitynullJSON has no Infinity; mapped to null
NaNNaNnullJSON has no NaN; mapped to null

Frequently Asked Questions

The parser normalizes indentation by detecting the first indented line's whitespace character (tab or space) and unit size. If the first indent uses 2 spaces, all subsequent indentation is measured in multiples of 2 spaces. Mixing tabs and spaces within the same file will trigger a parse error because the indent level becomes ambiguous. Convert your file to consistent whitespace before pasting.
String interpolation (e.g., "Hello #{name}") requires a CoffeeScript runtime to evaluate the expression inside #{}. Since this is a static format converter - not a CoffeeScript interpreter - the interpolation syntax is preserved as a literal string in the JSON output. If you need evaluated values, resolve them in your CoffeeScript environment first, then convert the resulting CSON.
JSON (RFC 8259) does not support Infinity, NaN, or undefined as value types. The converter maps all three to null. If your application logic depends on distinguishing these, you will need to implement a custom reviver function when parsing the resulting JSON. This is a fundamental limitation of the JSON specification, not the converter.
Yes. The recursive descent parser has no hard-coded depth limit. However, JavaScript engines typically impose a call stack limit around 10,000-25,000 frames depending on the browser. For practical configuration files, nesting beyond 50 levels is extremely rare. Files with pathological nesting (>5,000 levels) may cause a stack overflow, in which case the converter will display a parse error.
Yes. The parser processes keys in the order they appear in the source text and builds the output object sequentially. JSON.stringify preserves insertion order for string keys in all modern JavaScript engines (V8, SpiderMonkey, JavaScriptCore). Integer-like keys (e.g., "1", "2") may be reordered by the engine per the ECMAScript specification, but this is rare in typical configuration files.
Heredoc strings (delimited by ''' or """) capture all content between the delimiters. The converter strips the common leading whitespace from all lines within the heredoc (dedent), matching CoffeeScript's behavior. The opening delimiter's line is not included in the content. Trailing newlines before the closing delimiter are also stripped.