conl 1.7.0

CONL is a post-modern configuration language
Documentation

CONL is a post-minimal, human-centric configuration language.

It is designed as a drop-in replacement for JSON/INI/YAML/TOML/etc... for when you want a file that users are comfortable editing by hand.

Features:

  • A JSON-like data model of maps, lists and scalars.
  • An INI-like type system, where type inference is deferred until parse time.
  • A (simplified) YAML-like syntax, where indentation defines structure.

Design criteria:

  • Easy to read. CONL files parse unambiguously to both humans and machines.
  • Easy to edit. No need to spend time balancing brackets.
  • JSON-iteroperable. You can validate a CONL document with JSON schema if you want.
  • Easy to parse. Building a CONL parser is a fun afternoon, not a week of deciphering edge-cases.

Consider this example file:

Syntax

CONL uses indentation for structure. This provides an advantage over JSON in that common operations (like commenting out a line) do not make the document invalid, and an advantage over TOML/INI in that you can construct arbitrary list/map nestings instead of just "tables".

map
  key1 = value1
  key2 = value2
  ;...

list
  = value1
  = value2

Without any special syntax, keys can contain any character except ;, =, \r, \n and values can contain any character except ;, \r, \n.

key containing spaces = value with = and "quotes"!

If your value contains newlines (or ;) use multiline syntax. The syntax highlighting hint is optional and is not parsed, but gives you nice highlighting in modern editors.

init_script = """bash
  #!/bin/bash

  echo "hello world";

In the rare case you need more flexiblity, for example to preserve leading/trailing whitespace, or to represent the presence of the empty string, you can use a quoted literal:

"" = " wow\r\nlook at my cat \{1F431}"

Quoting is not meaningful. CONL uses deferred typing to ensure that the application receives the type it needs without users having to remember the syntax.

enabled = true
enabled = "true" ; equivalent to enabled = true
enabled = """    ; equivalent to enabled = true
   true

This also allows for a richer set of types. Instead of downcasting to just numbers, you can have fields that expect specific units without adding more syntactic noise:

max_space = 10 GB
timeout = 10s
country_code = no

CONL uses ; for comments. This means that common values like HTML colors don't require quotes.

color = #ff0000 ; pure red

Any JSON/YAML/TOML document can be converted to CONL, but the reverse (to do it propertly) requires a schema to ensure the correct type-syntax is generated (or you can guess ;).

If you'd like to build your own implementation, spec.conl contains a relatively complete specification of the syntax.

Why?

Why not? I was inspired to create CONL by this excellent INI critique of TOML. It reminded me that my struggles to write TOML or YAML by hand were not due to failings on my part, but due to the inherent complexity of a "minimal" format that has four syntaxes for strings, and eleven other data-types to contend with.

In my day-to-day life I spend a non-trivial amount of time editing configuration files that are either giant chunks of YAML (Github workflows, Kubernetes manifests...), giant chunks of JSON-with-comments files (Zed's configuration files), or TOML (Rust cargo files). What if there were one format that could do it all, and do it all in a relatively easy way.