From 53897b441a100da397e02f34752d1831715583e0 Mon Sep 17 00:00:00 2001
From: zkat KDL is a small, pleasing document language with xml-like semantics that looks
-like you're invoking a bunch of CLI commands! It's meant to be used both as a
-serialization format and a configuration language, much like JSON, YAML, or
+ KDL is a small, pleasant document language with XML-like node semantics that
+looks like you're invoking a bunch of CLI commands! It's meant to be used both
+as a serialization format and a configuration language, much like JSON, YAML, or
XML. It looks like this: There's a living specification, as well as various
-implementations. You can also check out the FAQ to
-answer all your burning questions! In addition to a spec for KDL itself, there are also standard specs for a KDL
-Query Language based
-on CSS selectors, and a KDL Schema
-Language loosely
-based on JSON Schema. The language is based on SDLang, with a number of
-modifications and clarifications on its syntax and behavior. The current version of the KDL spec is For more details, see the overview below. There's a living
+specification, as well as
+various implementations. You can also check out the
+FAQ to answer all your burning questions! The current version of the KDL spec is In addition to a spec for KDL itself, there are specifications for a KDL Query
+Language based on CSS selectors, and a KDL Schema
+Language loosely based on JSON Schema. The language is based on SDLang, with a number of
+modifications and clarifications on its syntax and behavior.
+We are grateful for their work as an inspiration to ours. KDL 2.0.0 has been finalized, and no further changes are expected. For questions
+about KDL and discussions, please see the discussions
+page. For minor editorial fixes or
+critical spec errata, please feel free to file an
+issue. A lot of folks have started picking up KDL for both personal projects, and
+larger open source, and even proprietary projects! This section includes a list
+of some examples of KDL in the wild (either v1, v2, or both): [!INFO] There are two major versions of KDL. Different libraries may support one or the
+other, or even provide a "hybrid" mode where both versions are attempted, since
+there's no data ambiguity between v1 and v2 documents. * Supported by earlier library version A KDL node is a node name, followed by zero or more "arguments", and
+ A KDL node is a node name string, followed by zero or more "arguments", and
children. You can also have multiple values in a single node! Nodes can have properties. Nodes can have properties, with string keys. And they can have nested child nodes, too! Nodes without children are terminated by a newline, a semicolon, or the end of
a file stream: KDL supports 4 data types: It supports two different formats for string input: escaped and raw. Both types of string can be multiline as-is, without a different syntax: And for raw strings, you can add any number of # after the r and the last " to
-disambiguate literal " characters: It supports three different formats for string input: identifiers, quoted, and raw. You don't have to quote strings unless any the following apply: In essence, if it can get confused for other KDL or KQL syntax, it needs
+quotes. Both types of quoted string can be written across multiple lines by using triple
+quotes ( Raw strings, which do not support You can add any number of There's 4 ways to represent numbers in KDL. KDL does not prescribe any
+ There are 4 ways to represent numbers in KDL. KDL does not prescribe any
representation for these numbers, and it's entirely up to individual
implementations whether to represent all numbers with a single type, or to
have different representations for different forms. KDL has regular decimal-radix numbers, with optional decimal part, as well as
an optional exponent. And using the appropriate prefix, you can also enter hexadecimal, octal, and
binary literals: Finally, all numbers can have underscores to help readability: KDL supports C-style comments, both line-based and multiline. Multiline
comments can be nested. On top of that, KDL supports
-package {
- name "my-pkg"
- version "1.2.3"
-
- dependencies {
- // Nodes can have standalone values as well as
- // key/value pairs.
- lodash "^3.2.1" optional=true alias="underscore"
- }
-
- scripts {
- // "Raw" and multi-line strings are supported.
- build r#"
- echo "foo"
- node -c "console.log('hello, world!');"
- echo "foo" > some-file.txt
- "#
- }
-
- // `\` breaks up a single node across multiple lines.
- the-matrix 1 2 3 \
- 4 5 6 \
- 7 8 9
-
- // "Slashdash" comments operate at the node level,
- // with just `/-`.
- /-this-is-commented {
- this "entire" "node" {
- "is" "gone"
- }
- }
-}1.0.0.
+package {
+ name my-pkg
+ version "1.2.3"
+
+ dependencies {
+ // Nodes can have standalone values as well as
+ // key/value pairs.
+ lodash "^3.2.1" optional=#true alias=underscore
+ }
+
+ scripts {
+ // "Raw" and dedented multi-line strings are supported.
+ message """
+ hello
+ world
+ """
+ build #"""
+ echo "foo"
+ node -c "console.log('hello, world!');"
+ echo "foo" > some-file.txt
+ """#
+ }
+
+ // `\` breaks up a single node across multiple lines.
+ the-matrix 1 2 3 \
+ 4 5 6 \
+ 7 8 9
+
+ // "Slashdash" comments operate at the node level,
+ // with just `/-`.
+ /-this-is-commented {
+ this entire node {
+ is gone
+ }
+ }
+}
+2.0.0. For legacy KDL, please refer to
+the KDL 1.0 spec. All
+users are encouraged to migrate. Migration is forward-and-backward-compatible
+and safe, and can be automated.Design and Discussion
+Used By
+
+
+Implementations
+
+
+
+
+
+
+
+
+
+Language
+Implementation
+v1
+v2
+Notes
+
+
+C
+ckdl
+✅
+✅
+
+
+
+C#/.NET
+Kadlet
+✅
+✖️
+
+
+
+C++
+kdlpp
+✅
+✅
+part of ckdl, requires C++20
+
+
+Common Lisp
+kdlcl
+✅
+✖️
+
+
+
+Crystal
+kdl-cr
+✅
+✖️
+
+
+
+Dart
+kdl-dart
+✅
+✖️
+
+
+
+Elixir
+kuddle
+✅
+✅
+
+
+
+Go
+gokdl
+✅
+✖️
+
+
+
+Go
+kdl-go
+✅
+✖️
+
+
+
+Haskell
+Hustle
+✅
+✖️
+
+
+
+Java
+kdl4j
+✅
+✖️
+
+
+
+JavaScript
+@bgotink/kdl
+✅*
+✅
+Format/comment-preserving parser
+
+
+JavaScript
+@virtualstate/kdl
+✅
+✖️
+query only, JSX based
+
+
+JavaScript
+kdljs
+✅
+✖️
+
+
+
+Lua
+kdlua
+✅
+✖️
+
+
+
+Nim
+kdl-nim
+✅
+✖️
+
+
+
+OCaml
+ocaml-kdl
+✅
+✖️
+
+
+
+PHP
+kdl-php
+✅
+✖️
+
+
+
+Python
+ckdl
+✅
+✅
+
+
+
+Python
+cuddle
+✅
+✖️
+
+
+
+Python
+kdl-py
+✅
+✅
+
+
+
+Ruby
+kdl-rb
+✅
+✖️
+
+
+
+Rust
+kdl-rs
+✅*
+✅
+Format/comment-preserving parser
+
+
+Rust
+knuffel
+✅
+✖️
+Serde-style derive macros (not actual Serde)
+
+
+Swift
+kdl-swift
+✅
+✖️
+
+
+
+
+XSLT
+xml2kdl
+✅
+✖️
+
+ Editor Support
+
+
Overview
Basics
-
+title "Hello, World"title "Hello, World"
+
-bookmarks 12 15 188 1234
+author "Alex Monad" email="alex@example.com" active=true
+bookmarks 12 15 188 1234
+author "Alex Monad" email=alex@example.com active=#true
+
+contents {
- section "First section" {
- paragraph "This is the first paragraph"
- paragraph "This is the second paragraph"
- }
-}contents {
+ section "First section" {
+ paragraph "This is the first paragraph"
+ paragraph "This is the second paragraph"
+ }
+}
+
+node1; node2; node3;node1; node2; node3;
+Values
-
"hello world"unquoted, "hello world", or #"hello world"#123.45true and falsenull#true and #false#nullStrings
-
-node "this\nhas\tescapes"
-other r"C:\Users\zkat\"
-string "my
-multiline
-value"
+other-raw r#"hello"world"#
+node1 this-is-a-string
+node2 "this\nhas\tescapes"
+node3 #"C:\Users\zkat\raw\string"#
+
+
+[]{}()\/#";=.true, false, null, inf, -inf, or nan.+/-/./-.,+. and a digit.
+(aka "looks like a number")""") followed immediately by a newline. Additionally, common
+indentation shared with the line containing the closing quotes will be
+stripped/dedented:
+string """
+ my
+ multiline
+ value
+ """
+\ escapes and can be used when you want
+certain kinds of strings to look nicer without having to escape a lot:
+exec #"""
+ echo "foo"
+ echo "bar"
+ cd C:\path\to\dir
+ """#
+
+regex #"\d{3} "[^/"]+""#
+#s before and after the opening and
+closing # to disambiguate literal closing #" sequences:other-raw ##"hello#"world"##
+Numbers
-
+num 1.234e-42num 1.234e-42
+
+my-hex 0xdeadbeef
-my-octal 0o755
-my-binary 0b10101101my-hex 0xdeadbeef
+my-octal 0o755
+my-binary 0b10101101
+
+bignum 1_000_000bignum 1_000_000
+Comments
+// C style
-
-/*
-C style multiline
-*/
-
-tag /*foo=true*/ bar=false
-
-/*/*
-hello
-*/*/// C style
+
+/*
+C style multiline
+*/
+
+tag /*foo=#true*/ bar=#false
+
+/*/*
+hello
+*/*/
+/- "slashdash" comments, which can be used to
-comment out individual nodes, arguments, or children:
+comment out individual nodes, entries, or child blocks:// This entire node and its children are all commented out.
-/-mynode "foo" key=1 {
- a
- b
- c
-}
-
-mynode /-"commented" "not commented" /-key="value" /-{
- a
- b
-}
// This entire node and its children are all commented out.
+/-mynode foo key=1 {
+ a
+ b
+ c
+}
+
+mynode /-commented "not commented" /-key=value /-{
+ a
+ b
+}
+// The above is equivalent to:
+mynode "not commented"
+
KDL supports type annotations on both values and nodes. These can be arbitrary, but can be used by individual implementations or use-cases to constrain KDL's basic types. A number of type names are also reserved to have specific meanings.
-numbers (u8)10 (i32)20 myfloat=(f32)1.5 {
- strings (uuid)"123e4567-e89b-12d3-a456-426614174000" (date)"2021-02-03" filter=(regex)r"$\d+"
- (author)person name="Alex"
-}
+numbers (u8)10 (i32)20 myfloat=(f32)1.5 {
+ strings (uuid)"123e4567-e89b-12d3-a456-426614174000" (date)"2021-02-03" filter=(regex)#"$\d+"#
+ (author)person name=Alex
+}
+
// Nodes can be separated into multiple lines
-title \
- "Some title"
-
-
-// Files must be utf8 encoded!
-smile "😁"
-
-// Instead of anonymous nodes, nodes and properties can be wrapped
-// in "" for arbitrary node names.
-"!@#$@$%Q#$%~@!40" "1.2.3" "!!!!!"=true
-
-// The following is a legal bare identifier:
-foo123~!@#$%^&*.:'|?+ "weeee"
-
-// And you can also use unicode!
-ノード お名前="☜(゚ヮ゚☜)"
-
-// kdl specifically allows properties and values to be
-// interspersed with each other, much like CLI commands.
-foo bar=true "baz" quux=false 1 2 3
-
-KDL is still extremely new, and discussion about the format should happen over -on the discussions page in the -Github repo. Feel free to jump in and give us your 2 cents!
+// Nodes can be separated into multiple lines
+title \
+ "Some title"
+
+
+// Files must be utf8 encoded!
+smile 😁
+
+// Node names and property keys are just strings, so you can write them like
+// quoted or raw strings, too!
+"illegal(){}[]/\\=#;identifier" #"1.2.3"# "#false"=#true
+
+// Identifiers are very flexible. The following is a legal bare identifier:
+-<123~!$@%^&*,.:'`|?+>
+
+// And you can also use non-ASCII unicode!
+ノード お名前=ฅ^•ﻌ•^ฅ
+
+// kdl specifically allows properties and values to be
+// interspersed with each other, much like CLI commands.
+foo bar=#true baz quux=#false 1 2 3
+
Same as "cuddle".
Because nothing out there felt quite right. The closest one I found was SDLang, but that had some design choices I disagreed with.
+SDLang is designed for use cases that are not interesting to me, but are very -relevant to the D-lang community. KDL is very similar in many ways, but is -different in the following ways:
+SDLang is an excellent base, but I wanted some details ironed out, and some +things removed that only really made sense for SDLang's current use-cases, including +some restrictions about data representation. KDL is very similar in many ways, except:
/-) comments are great and useful!node foo=bar, vs node foo="bar").(date)"2021-02-03", (binary)"deadbeefbadc0ffee".r"foo"), instead of backticks."""<newline> and their lines are automatically
+"dedented" to match their closing quotes' indentation level.# (#"foo\bar"#), instead of backticks. This,
+while more verbose, allows embedding of languages, especially scripting
+languages, that use this syntax on a regular basis, without additional escaping
+(e.g. bash and JavaScript).-.: is a legal identifier character, and applications
+can choose to implement namespaces as they see fit."123" "value"=1 is
a valid node, for example. This makes it easier to use KDL for
-representing arbitrary key/value pairs.Yes. I have. Please stop linking me to it.
@@ -296,7 +565,8 @@ unfortunate mistakes. It also has much more flexibility around how to represent data.If you need to interoperate with a service that consumes or emits JSON, or for some other reason have need to write "JSON in KDL", we have JiK, an official -microsyntax for losslessly encoding JSON.
+microsyntax for losslessly encoding +JSON.It nests very poorly. It doesn't fare well with large files.
If you need to interoperate with a service that consumes or emits XML, or for some other reason have need to write "XML in KDL", we have XiK, an official microsyntax for losslessly encoding XML.
-