447 lines
33 KiB
HTML
447 lines
33 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta
|
|
name="description"
|
|
content="kdl is a document language, mostly based on SDLang, with xml-like semantics that looks like you're invoking a bunch of CLI commands!"
|
|
/>
|
|
<title>The KDL Document Language</title>
|
|
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon-DYakp7eY.png">
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32-DyPo_U_s.png">
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16-CySQqJXs.png">
|
|
<link rel="manifest" href="/assets/site-n2cPdmrr.webmanifest">
|
|
<meta name="msapplication-TileColor" content="#da532c">
|
|
<meta name="theme-color" content="#ffffff">
|
|
<link rel="stylesheet" crossorigin href="/assets/global-DvdzMk0y.css">
|
|
</head>
|
|
<body>
|
|
<main><header class="pt-20 pb-10 px-4">
|
|
<img src="/assets/logo-with-tagline-CHWKIwA-.svg" class="mx-auto h-40" alt="KDL: A cuddly document language">
|
|
</header>
|
|
<section class="kdl-section" id="description">
|
|
<p>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:</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">package</span><span style="color:#D8DEE9FF"> {</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> name</span><span style="color:#A3BE8C"> my-pkg</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> version</span><span style="color:#A3BE8C"> "1.2.3"</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#81A1C1"> dependencies</span><span style="color:#D8DEE9FF"> {</span></span>
|
|
<span class="line"><span style="color:#616E88"> // Nodes can have standalone values as well as</span></span>
|
|
<span class="line"><span style="color:#616E88"> // key/value pairs.</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> lodash</span><span style="color:#A3BE8C"> "^3.2.1"</span><span style="color:#8FBCBB"> optional</span><span style="color:#ECEFF4">=</span><span style="color:#81A1C1">#true</span><span style="color:#8FBCBB"> alias</span><span style="color:#ECEFF4">=</span><span style="color:#A3BE8C">underscore</span></span>
|
|
<span class="line"><span style="color:#D8DEE9FF"> }</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#81A1C1"> scripts</span><span style="color:#D8DEE9FF"> {</span></span>
|
|
<span class="line"><span style="color:#616E88"> // "Raw" and dedented multi-line strings are supported.</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> message</span><span style="color:#A3BE8C"> """</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> hello</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> world</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> """</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> build</span><span style="color:#A3BE8C"> #"""</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> echo "foo"</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> node -c "console.log('hello, world!');"</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> echo "foo" > some-file.txt</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> """#</span></span>
|
|
<span class="line"><span style="color:#D8DEE9FF"> }</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#616E88"> // `\` breaks up a single node across multiple lines.</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> the-matrix</span><span style="color:#B48EAD"> 1</span><span style="color:#B48EAD"> 2</span><span style="color:#B48EAD"> 3</span><span style="color:#D8DEE9FF"> \</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> 4</span><span style="color:#B48EAD"> 5</span><span style="color:#B48EAD"> 6</span><span style="color:#D8DEE9FF"> \</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> 7</span><span style="color:#B48EAD"> 8</span><span style="color:#B48EAD"> 9</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#616E88"> // "Slashdash" comments operate at the node level,</span></span>
|
|
<span class="line"><span style="color:#616E88"> // with just `/-`.</span></span>
|
|
<span class="line"><span style="color:#616E88"> /-this-is-commented {</span></span>
|
|
<span class="line"><span style="color:#616E88"> this entire node {</span></span>
|
|
<span class="line"><span style="color:#616E88"> is gone</span></span>
|
|
<span class="line"><span style="color:#616E88"> }</span></span>
|
|
<span class="line"><span style="color:#D8DEE9FF"> }</span></span>
|
|
<span class="line"><span style="color:#D8DEE9FF">}</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>For more details, see the <a href="#overview">overview below</a>. <a href="./play/">Play with it in your
|
|
browser!</a></p>
|
|
<p>There's a living
|
|
<a href="/spec">specification</a>, as well as
|
|
various <a href="#implementations">implementations</a>. You can also check out the
|
|
<a href="#faq">FAQ</a> to answer all your burning questions!</p>
|
|
<p>The current version of the KDL spec is
|
|
<a href="/spec">KDL 2.0.0</a>. For legacy KDL,
|
|
please refer to the <a href="/spec-v1">KDL 1.0.0
|
|
spec</a>. All users are
|
|
encouraged to migrate. <a href="/spec#compatibility">Migration is forward-and-backward-compatible and
|
|
safe</a>, and can
|
|
be automated.</p>
|
|
<p>In addition to a spec for KDL itself, there are specifications for <a href="https://github.com/kdl-org/kdl/blob/main/QUERY-SPEC.md">a KDL Query
|
|
Language</a> based on CSS selectors, and <a href="https://github.com/kdl-org/kdl/blob/main/SCHEMA-SPEC.md">a KDL Schema
|
|
Language</a> loosely based on JSON Schema.</p>
|
|
<p>The language is based on <a href="https://sdlang.org">SDLang</a>, with a <a href="#why-not-sdlang">number of
|
|
modifications and clarifications on its syntax and behavior</a>.
|
|
We are grateful for their work as an inspiration to ours.</p>
|
|
</section>
|
|
<section class="kdl-section" id="design-and-discussion">
|
|
<h2>Design and Discussion</h2>
|
|
<p>KDL 2.0.0 has been finalized, and no further changes are expected. For questions
|
|
about KDL and discussions, please see the <a href="https://github.com/kdl-org/kdl/discussions">discussions
|
|
page</a>. For minor editorial fixes or
|
|
critical spec errata, please feel free to <a href="https://github.com/kdl-org/kdl/issues">file an
|
|
issue</a>.</p>
|
|
</section>
|
|
<section class="kdl-section" id="used-by">
|
|
<h2>Used By</h2>
|
|
<p>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):</p>
|
|
<ul>
|
|
<li><a href="https://zellij.dev">Zellij</a> - Terminal workspace/multiplexer</li>
|
|
<li><a href="https://github.com/YaLTeR/niri">Niri</a> - Scrollable-tiling window manager for Wayland</li>
|
|
<li><a href="https://github.com/speced/bikeshed">Bikeshed</a> (<a href="https://github.com/speced/bikeshed-boilerplate/blob/main/boilerplate/doctypes.kdl">here</a> and <a href="https://github.com/speced/bikeshed-data/blob/main/data/manifest.txt">here</a>) - Specification pre-processor used by CSS, C++, WHATWG, various W3C working groups, and others.</li>
|
|
<li><a href="https://orogene.dev">orogene</a> - Lightning-fast JavaScript package manager</li>
|
|
<li><a href="https://onyxlang.io/">Onyx</a> - An efficient, procedural, and pragmatic programming language that compiles to WASM. Used for package manifests.</li>
|
|
<li><a href="https://github.com/pop-os/system76-scheduler">Pop!_OS/System76 Scheduler</a> - Scheduling service which optimizes Linux's CPU scheduler and makes it go faster.</li>
|
|
<li><a href="https://patitotective.github.io/ImStyle/">ImStyle</a> - ImGui application styling with Nim and KDL</li>
|
|
<li><a href="https://github.com/CAD97/fmod-rs">fmod-rs</a> - Rust bindings to FMOD Core and FMOD Studio</li>
|
|
<li><a href="https://mise.jdx.dev/">mise</a> - dev tools, env vars, task runner</li>
|
|
<li><a href="https://github.com/camping/camping">Camping</a> - Ruby web microframework</li>
|
|
<li><a href="https://ironvault.quest">Iron Vault</a> - VTT (Virtual Tabletop) plugin for Obsidian for the Ironsworn family of games</li>
|
|
<li>You?</li>
|
|
</ul>
|
|
</section>
|
|
<section class="kdl-section" id="implementations">
|
|
<h2>Implementations</h2>
|
|
<ul>
|
|
<li>C - <a href="https://github.com/tjol/ckdl">ckdl</a>*</li>
|
|
<li>C#/.NET - <a href="https://github.com/oledfish/Kadlet">Kadlet</a></li>
|
|
<li>C++ - <a href="https://github.com/tjol/ckdl">kdlpp</a>* (part of ckdl, requires C++20)</li>
|
|
<li>Common Lisp - <a href="https://github.com/chee/kdlcl">kdlcl</a></li>
|
|
<li>Crystal - <a href="https://github.com/danini-the-panini/kdl-cr">kdl-cr</a></li>
|
|
<li>Dart - <a href="https://github.com/danini-the-panini/kdl-dart">kdl-dart</a>*</li>
|
|
<li>Elixir - <a href="https://github.com/IceDragon200/kuddle">kuddle</a>*</li>
|
|
<li>Go -
|
|
<ul>
|
|
<li><a href="https://github.com/lunjon/gokdl">gokdl</a></li>
|
|
<li><a href="https://github.com/sblinch/kdl-go">kdl-go</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>Haskell - <a href="https://github.com/fuzzypixelz/Hustle">Hustle</a></li>
|
|
<li>Java - <a href="https://github.com/hkolbeck/kdl4j">kdl4j</a></li>
|
|
<li>JavaScript -
|
|
<ul>
|
|
<li><a href="https://github.com/bgotink/kdl">@bgotink/kdl</a>* (Format/comment-preserving parser)</li>
|
|
<li><a href="https://github.com/virtualstate/kdl">@virtualstate/kdl</a> (query only, JSX based)</li>
|
|
<li><a href="https://github.com/kdl-org/kdljs">kdljs</a>*</li>
|
|
</ul>
|
|
</li>
|
|
<li>Lua - <a href="https://github.com/danini-the-panini/kdlua">kdlua</a></li>
|
|
<li>Nim - <a href="https://github.com/Patitotective/kdl-nim">kdl-nim</a></li>
|
|
<li>OCaml - <a href="https://github.com/Bannerets/ocaml-kdl">ocaml-kdl</a></li>
|
|
<li>PHP - <a href="https://github.com/kdl-org/kdl-php">kdl-php</a></li>
|
|
<li>Python -
|
|
<ul>
|
|
<li><a href="https://github.com/tjol/ckdl">ckdl</a>*</li>
|
|
<li><a href="https://github.com/djmattyg007/python-cuddle">cuddle</a></li>
|
|
<li><a href="https://github.com/tabatkins/kdlpy">kdl-py</a>*</li>
|
|
</ul>
|
|
</li>
|
|
<li>Ruby - <a href="https://github.com/danini-the-panini/kdl-rb">kdl-rb</a>*</li>
|
|
<li>Rust -
|
|
<ul>
|
|
<li><a href="https://github.com/kdl-org/kdl-rs">kdl-rs</a> (Format/comment-preserving parser)*</li>
|
|
<li><a href="https://crates.io/crates/knus/">knus</a> (Serde-<em>style</em> derive macros (not actual Serde))</li>
|
|
</ul>
|
|
</li>
|
|
<li>Swift - <a href="https://github.com/danini-the-panini/kdl-swift">kdl-swift</a></li>
|
|
<li>XSLT - <a href="https://github.com/Devasta/XML2KDL">xml2kdl</a></li>
|
|
</ul>
|
|
<p>* Supports both KDL v1 and v2</p>
|
|
</section>
|
|
<section class="kdl-section" id="editor-support">
|
|
<h2>Editor Support</h2>
|
|
<ul>
|
|
<li><a href="https://plugins.jetbrains.com/plugin/20136-kdl-document-language">Intellij IDEA</a></li>
|
|
<li><a href="https://packagecontrol.io/packages/KDL">Sublime Text</a>*</li>
|
|
<li><a href="https://github.com/tree-sitter-grammars/tree-sitter-kdl">TreeSitter</a> (neovim, among others)</li>
|
|
<li><a href="https://marketplace.visualstudio.com/items?itemName=kdl-org.kdl&ssr=false#review-details">VS Code</a>*</li>
|
|
<li><a href="https://github.com/imsnif/kdl.vim">vim</a></li>
|
|
</ul>
|
|
<p>* Supports KDL 2.0.0</p>
|
|
</section>
|
|
<section class="kdl-section" id="overview">
|
|
<h2>Overview</h2>
|
|
<h3>Basics</h3>
|
|
<p>A KDL node is a node name string, followed by zero or more "arguments", and
|
|
children.</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">title</span><span style="color:#A3BE8C"> "Hello, World"</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>You can also have multiple values in a single node!</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">bookmarks</span><span style="color:#B48EAD"> 12</span><span style="color:#B48EAD"> 15</span><span style="color:#B48EAD"> 188</span><span style="color:#B48EAD"> 1234</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>Nodes can have properties, with string keys.</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">author</span><span style="color:#A3BE8C"> "Alex Monad"</span><span style="color:#8FBCBB"> email</span><span style="color:#ECEFF4">=</span><span style="color:#A3BE8C">alex@example.com</span><span style="color:#8FBCBB"> active</span><span style="color:#ECEFF4">=</span><span style="color:#81A1C1">#true</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>And they can have nested child nodes, too!</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">contents</span><span style="color:#D8DEE9FF"> {</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> section</span><span style="color:#A3BE8C"> "First section"</span><span style="color:#D8DEE9FF"> {</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> paragraph</span><span style="color:#A3BE8C"> "This is the first paragraph"</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> paragraph</span><span style="color:#A3BE8C"> "This is the second paragraph"</span></span>
|
|
<span class="line"><span style="color:#D8DEE9FF"> }</span></span>
|
|
<span class="line"><span style="color:#D8DEE9FF">}</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>Nodes without children are terminated by a newline, a semicolon, or the end of
|
|
a file stream:</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">node1</span><span style="color:#D8DEE9FF">;</span><span style="color:#81A1C1"> node2</span><span style="color:#D8DEE9FF">;</span><span style="color:#81A1C1"> node3</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<h3>Values</h3>
|
|
<p>KDL supports 4 data types:</p>
|
|
<ul>
|
|
<li>Strings: <code>unquoted</code>, <code>"hello world"</code>, or <code>#"hello world"#</code></li>
|
|
<li>Numbers: <code>123.45</code>, <code>0xdeadbeef</code>, <code>#inf</code>, <code>#-inf</code>, <code>#nan</code></li>
|
|
<li>Booleans: <code>#true</code> and <code>#false</code></li>
|
|
<li>Null: <code>#null</code></li>
|
|
</ul>
|
|
<h4>Strings</h4>
|
|
<p>It supports three different formats for string input: unquoted, quoted, and raw.</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">node1</span><span style="color:#A3BE8C"> this-is-a-string</span></span>
|
|
<span class="line"><span style="color:#81A1C1">node2</span><span style="color:#A3BE8C"> "this</span><span style="color:#EBCB8B">\n</span><span style="color:#A3BE8C">has</span><span style="color:#EBCB8B">\t</span><span style="color:#A3BE8C">escapes"</span></span>
|
|
<span class="line"><span style="color:#81A1C1">node3</span><span style="color:#A3BE8C"> #"C:\Users\zkat\raw\string"#</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>You don't have to quote strings unless any the following apply:</p>
|
|
<ul>
|
|
<li>The string contains whitespace.</li>
|
|
<li>The string contains any of <code>[]{}()\/#";=</code>.</li>
|
|
<li>The string is one of <code>true</code>, <code>false</code>, <code>null</code>, <code>inf</code>, <code>-inf</code>, or <code>nan</code>.</li>
|
|
<li>The strings starts with a digit, or <code>+</code>/<code>-</code>/<code>.</code>/<code>-.</code>,<code>+.</code> and a digit.
|
|
(aka "looks like a number")</li>
|
|
</ul>
|
|
<p>In essence, if it can get confused for other KDL or KQL syntax, it needs
|
|
quotes.</p>
|
|
<p>Both types of quoted string can be written across multiple lines by using triple
|
|
quotes (<code>"""</code>) followed immediately by a newline. Additionally, common
|
|
indentation shared with the line containing the closing quotes will be
|
|
stripped/dedented:</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">string</span><span style="color:#A3BE8C"> """</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> my</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> multiline</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> value</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> """</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>Raw strings, which do not support <code>\</code> escapes and can be used when you want
|
|
certain kinds of strings to look nicer without having to escape a lot:</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">exec</span><span style="color:#A3BE8C"> #"""</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> echo "foo"</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> echo "bar"</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> cd C:\path\to\dir</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> """#</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#81A1C1">regex</span><span style="color:#A3BE8C"> #"\d{3} "[^/"]+""#</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>You can add any number of <code>#</code>s before and after the opening and
|
|
closing <code>#</code> to disambiguate literal closing <code>#"</code> sequences:</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">other-raw</span><span style="color:#A3BE8C"> ##"hello#"world"##</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<h4>Numbers</h4>
|
|
<p>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.</p>
|
|
<p>KDL has regular decimal-radix numbers, with optional decimal part, as well as
|
|
an optional exponent.</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">num</span><span style="color:#B48EAD"> 1.234e-42</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>And using the appropriate prefix, you can also enter hexadecimal, octal, and
|
|
binary literals:</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">my-hex</span><span style="color:#B48EAD"> 0xdeadbeef</span></span>
|
|
<span class="line"><span style="color:#81A1C1">my-octal</span><span style="color:#B48EAD"> 0o755</span></span>
|
|
<span class="line"><span style="color:#81A1C1">my-binary</span><span style="color:#B48EAD"> 0b10101101</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>Finally, all numbers can have underscores to help readability:</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">bignum</span><span style="color:#B48EAD"> 1_000_000</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<h3>Comments</h3>
|
|
<p>KDL supports C-style comments, both line-based and multiline. Multiline
|
|
comments can be nested.</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#616E88">// C style</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#616E88">/*</span></span>
|
|
<span class="line"><span style="color:#616E88">C style multiline</span></span>
|
|
<span class="line"><span style="color:#616E88">*/</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#81A1C1">tag</span><span style="color:#616E88"> /*foo=#true*/</span><span style="color:#8FBCBB"> bar</span><span style="color:#ECEFF4">=</span><span style="color:#81A1C1">#false</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#616E88">/*/*</span></span>
|
|
<span class="line"><span style="color:#616E88">hello</span></span>
|
|
<span class="line"><span style="color:#616E88">*/*/</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<p>On top of that, KDL supports <code>/-</code> "slashdash" comments, which can be used to
|
|
comment out individual nodes, entries, or child blocks:</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#616E88">// This entire node and its children are all commented out.</span></span>
|
|
<span class="line"><span style="color:#616E88">/-mynode foo key=1 {</span></span>
|
|
<span class="line"><span style="color:#616E88"> a</span></span>
|
|
<span class="line"><span style="color:#616E88"> b</span></span>
|
|
<span class="line"><span style="color:#616E88"> c</span></span>
|
|
<span class="line"><span style="color:#616E88">}</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#81A1C1">mynode</span><span style="color:#616E88"> /-commented </span><span style="color:#A3BE8C">"not commented"</span><span style="color:#616E88"> /-key=value /-{</span></span>
|
|
<span class="line"><span style="color:#616E88"> a</span></span>
|
|
<span class="line"><span style="color:#616E88"> b</span></span>
|
|
<span class="line"><span style="color:#616E88">}</span></span>
|
|
<span class="line"><span style="color:#616E88">// The above is equivalent to:</span></span>
|
|
<span class="line"><span style="color:#81A1C1">mynode</span><span style="color:#A3BE8C"> "not commented"</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<h3>Type Annotations</h3>
|
|
<p>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.</p>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">numbers</span><span style="color:#A3BE8C"> (u8)10</span><span style="color:#A3BE8C"> (i32)20</span><span style="color:#8FBCBB"> myfloat</span><span style="color:#ECEFF4">=</span><span style="color:#A3BE8C">(f32)1.5</span><span style="color:#D8DEE9FF"> {</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> strings</span><span style="color:#A3BE8C"> (uuid)"123e4567-e89b-12d3-a456-426614174000"</span><span style="color:#A3BE8C"> (date)"2021-02-03"</span><span style="color:#8FBCBB"> filter</span><span style="color:#ECEFF4">=</span><span style="color:#A3BE8C">(regex)#"$\d+"#</span></span>
|
|
<span class="line"><span style="color:#81A1C1"> (author)person</span><span style="color:#8FBCBB"> name</span><span style="color:#ECEFF4">=</span><span style="color:#A3BE8C">Alex</span></span>
|
|
<span class="line"><span style="color:#D8DEE9FF">}</span></span>
|
|
<span class="line"></span></code></pre>
|
|
<h3>More Details</h3>
|
|
<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#616E88">// Nodes can be separated into multiple lines</span></span>
|
|
<span class="line"><span style="color:#81A1C1">title</span><span style="color:#D8DEE9FF"> \</span></span>
|
|
<span class="line"><span style="color:#A3BE8C"> "Some title"</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#616E88">// Files must be utf8 encoded!</span></span>
|
|
<span class="line"><span style="color:#81A1C1">smile</span><span style="color:#D8DEE9FF"> 😁</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#616E88">// Node names and property keys are just strings, so you can write them like</span></span>
|
|
<span class="line"><span style="color:#616E88">// quoted or raw strings, too!</span></span>
|
|
<span class="line"><span style="color:#A3BE8C">"illegal(){}[]/</span><span style="color:#EBCB8B">\\</span><span style="color:#A3BE8C">=#;identifier"</span><span style="color:#A3BE8C"> #"1.2.3"#</span><span style="color:#A3BE8C"> "#false"</span><span style="color:#D8DEE9FF">=</span><span style="color:#81A1C1">#true</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#616E88">// Identifiers are very flexible. The following is a legal bare identifier:</span></span>
|
|
<span class="line"><span style="color:#81A1C1">-<123~!$@%^&*,.:'`|?+></span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#616E88">// And you can also use non-ASCII unicode!</span></span>
|
|
<span class="line"><span style="color:#81A1C1">ノード</span><span style="color:#8FBCBB"> お名前</span><span style="color:#ECEFF4">=</span><span style="color:#A3BE8C">ฅ^</span><span style="color:#D8DEE9FF">•</span><span style="color:#A3BE8C">ﻌ</span><span style="color:#D8DEE9FF">•</span><span style="color:#A3BE8C">^ฅ</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:#616E88">// kdl specifically allows properties and values to be</span></span>
|
|
<span class="line"><span style="color:#616E88">// interspersed with each other, much like CLI commands.</span></span>
|
|
<span class="line"><span style="color:#81A1C1">foo</span><span style="color:#8FBCBB"> bar</span><span style="color:#ECEFF4">=</span><span style="color:#81A1C1">#true</span><span style="color:#A3BE8C"> baz</span><span style="color:#8FBCBB"> quux</span><span style="color:#ECEFF4">=</span><span style="color:#81A1C1">#false</span><span style="color:#B48EAD"> 1</span><span style="color:#B48EAD"> 2</span><span style="color:#B48EAD"> 3</span></span>
|
|
<span class="line"></span></code></pre>
|
|
</section>
|
|
<section class="kdl-section" id="design-principles">
|
|
<h2>Design Principles</h2>
|
|
<ol>
|
|
<li>Human Maintainability</li>
|
|
<li>Flexibility</li>
|
|
<li>Cognitive Simplicity and Learnability</li>
|
|
<li>Ease of de/serialization</li>
|
|
<li>Ease of implementation</li>
|
|
</ol>
|
|
</section>
|
|
<section class="kdl-section" id="compatibility-with-json-and-xml">
|
|
<h2>Compatibility with JSON and XML</h2>
|
|
<p>There are two specifications for writing KDL that can be losslessly translated
|
|
between it and JSON or XML. These specifications define a stricter <em>subset</em> of
|
|
KDL that, even if not entirely idiomatic, is still valid and fits into the
|
|
data models of the other two languages:</p>
|
|
<ul>
|
|
<li><a href="https://github.com/kdl-org/kdl/blob/main/JSON-IN-KDL.md">JSON in KDL</a></li>
|
|
<li><a href="https://github.com/kdl-org/kdl/blob/main/JSON-IN-KDL.md">XML in KDL</a></li>
|
|
</ul>
|
|
</section>
|
|
<section class="kdl-section" id="compatibility-with-json-and-xml">
|
|
<h2>FAQ</h2>
|
|
<h4>How do you pronounce KDL?</h4>
|
|
<p>Same as "cuddle".</p>
|
|
<h4>Why yet another document language?</h4>
|
|
<p>Because nothing out there felt quite right. The closest one I found was
|
|
SDLang, but that had some design choices I disagreed with.</p>
|
|
<p><a name="why-not-sdlang"></a></p>
|
|
<h4>Ok, then, why not SDLang?</h4>
|
|
<p>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:</p>
|
|
<ul>
|
|
<li>The grammar and expected semantics are <a href="https://github.com/kdl-org/kdl/blob/main/SPEC.md">well-defined and specified</a>.
|
|
This was the original impetus for working on KDL, followed by details that
|
|
seemed like they could be improved.</li>
|
|
<li>There is only one "number" type. KDL does not prescribe representations, but
|
|
does have keywords for NaN, infinity, and negative infinity if decimal numbers
|
|
are intended to be represtented as IEEE754 floats.</li>
|
|
<li>Slashdash (<code>/-</code>) comments are great and useful!</li>
|
|
<li>Quoteless "identifier" strings (e.g. <code>node foo=bar</code>, vs <code>node foo="bar"</code>).</li>
|
|
<li>KDL does not have first-class date or binary data types. Instead, it
|
|
supports arbitrary type annotations for any custom data type you might need:
|
|
<code>(date)"2021-02-03"</code>, <code>(binary)"deadbeefbadc0ffee"</code>.</li>
|
|
<li>Values and properties can be interspersed with each other, rather than one
|
|
having to follow the other. It was not clear whether this was actually allowed in SDLang.</li>
|
|
<li>Multi-line strings are supported using <code>"""<newline></code> and their lines are automatically
|
|
"dedented" to match their closing quotes' indentation level.</li>
|
|
<li>Raw strings are written with <code>#</code> (<code>#"foo\bar"#</code>), 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).</li>
|
|
<li>KDL identifiers can use a wide range of UTF-8 and are much more lax about
|
|
valid characters than SDLang.</li>
|
|
<li>KDL does not support "anonymous" nodes. Instead, any string can be used as a
|
|
node name. For lists of arbitrary values, there is a convention of naming the nodes
|
|
simply <code>-</code>.</li>
|
|
<li>Namespaces are not supported, but <code>:</code> is a legal identifier character, and applications
|
|
can choose to implement namespaces as they see fit.</li>
|
|
<li>KDL supports arbitrary identifiers for node names and attribute
|
|
names, meaning you can use arbitrary strings for those: <code>"123" "value"=1</code> is
|
|
a valid node, for example. This makes it easier to use KDL for
|
|
representing arbitrary key/value pairs using child nodes.</li>
|
|
</ul>
|
|
<h4>Have you seen that one XKCD comic about standards?</h4>
|
|
<p>Yes. I have. Please stop linking me to it.</p>
|
|
<h4>What about YAML?</h4>
|
|
<p>YAML is a great, widespread language. Unlike KDL, which is node-based (like
|
|
XML or HTML), it's based on map and array data structures, which can provide
|
|
an easier serialization experience in some cases.</p>
|
|
<p>At the same time, YAML can be ambiguous about what types the data written into
|
|
it is. There's also a persistent issue where very large YAML files become
|
|
unmanageable, especially due to the significant indentation feature.</p>
|
|
<p>KDL is designed to avoid these particular pitfalls by always being explicit
|
|
about types, and having clearly-delimited scope (and the ability to
|
|
auto-indent/auto-format). Syntax errors are easier to catch, and large files
|
|
are (hopefully!) much more manageable.</p>
|
|
<h4>What about JSON?</h4>
|
|
<p>JSON is a great serialization language, but it can be very difficult to use as
|
|
a human configuration language. This is largely due to its very specific, very
|
|
strict syntax, as well as its lack of support for comments.</p>
|
|
<p>KDL, on the other hand, has great comment support, and has a much more
|
|
forgiving syntax without being so flexible as to allow certain classes of
|
|
unfortunate mistakes. It also has much more flexibility around how to
|
|
represent data.</p>
|
|
<p>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", <a href="https://github.com/kdl-org/kdl/blob/main/JSON-IN-KDL.md">we have JiK, an official
|
|
microsyntax for losslessly encoding
|
|
JSON</a>.</p>
|
|
<h4>What about TOML?</h4>
|
|
<p>It nests very poorly. It doesn't fare well with large files. Also, I felt some discomfort <a href="https://en.wikipedia.org/wiki/Tom_Preston-Werner#Resignation_from_GitHub">continuing to use and promote something by its creator</a>.</p>
|
|
<h4>What about XML?</h4>
|
|
<p>XML is actually pretty fantastic, and has long been a standard for data
|
|
exchange across many industries. At the same time, XML is known to be very
|
|
verbose, and editing it involves writing (and updating) matching tags. Another
|
|
large pitfall with XML is its lack of direct support for arbitrary string
|
|
key/value pairs, so what would be a simple <code>foo: x</code> in some languages has to
|
|
be represented as <code><entry name="foo" value="x" /></code> or something similar. XML
|
|
also functions great as a <strong>markup</strong> language. That is, it is easy to
|
|
intersperse with text, like HTML.</p>
|
|
<p>KDL, just like XML, is a node/element-based language, but with much more
|
|
lightweight syntax. It also adds the ability to apply anonymous values
|
|
directly to a node, rather than as children. That is, <code>nodename 1 2 3</code> instead
|
|
of <code><element><child>1</child><child>2</child>(etc)</element></code>. This can make
|
|
it much more manageable and readable as a human configuration language, and is
|
|
also less verbose when exchanging documents across APIs!</p>
|
|
<p>Finally, KDL is <strong>not</strong> a markup language. XML or HTML do a much better job of
|
|
"marking up" a text document with special tags, although KDL can still be
|
|
useful for templating engines that want to be more strict about text
|
|
fragments.</p>
|
|
<p>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", <a href="https://github.com/kdl-org/kdl/blob/main/XML-IN-KDL.md">we have XiK, an official
|
|
microsyntax for losslessly encoding XML</a>.</p>
|
|
</section>
|
|
</main>
|
|
</body>
|
|
</html>
|