diff --git a/index.html b/index.html index b694604..d9aae08 100644 --- a/index.html +++ b/index.html @@ -23,212 +23,466 @@ KDL: A cuddly document language
-

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:

-
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"
-    }
-  }
-}
-

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 1.0.0.

-

Play with it in your browser!

+
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
+    }
+  }
+}
+
+

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 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.

+

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.

+

Play with it in your browser (currently v1 only)!

+
+
+

Design and Discussion

+

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.

+
+
+

Used By

+

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):

+ +
+
+

Implementations

+
+

[!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.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LanguageImplementationv1v2Notes
Cckdl
C#/.NETKadlet✖️
C++kdlpppart of ckdl, requires C++20
Common Lispkdlcl✖️
Crystalkdl-cr✖️
Dartkdl-dart✖️
Elixirkuddle
Gogokdl✖️
Gokdl-go✖️
HaskellHustle✖️
Javakdl4j✖️
JavaScript@bgotink/kdl✅*Format/comment-preserving parser
JavaScript@virtualstate/kdl✖️query only, JSX based
JavaScriptkdljs✖️
Luakdlua✖️
Nimkdl-nim✖️
OCamlocaml-kdl✖️
PHPkdl-php✖️
Pythonckdl
Pythoncuddle✖️
Pythonkdl-py
Rubykdl-rb✖️
Rustkdl-rs✅*Format/comment-preserving parser
Rustknuffel✖️Serde-style derive macros (not actual Serde)
Swiftkdl-swift✖️
XSLTxml2kdl✖️
+

* Supported by earlier library version

+
+
+

Editor Support

+

Overview

Basics

-

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.

-
title "Hello, World"
+
title "Hello, World"
+

You can also have multiple values in a single node!

-
bookmarks 12 15 188 1234
-

Nodes can have properties.

-
author "Alex Monad" email="alex@example.com" active=true
+
bookmarks 12 15 188 1234
+
+

Nodes can have properties, with string keys.

+
author "Alex Monad" email=alex@example.com active=#true
+

And they can have nested child nodes, too!

-
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"
+  }
+}
+

Nodes without children are terminated by a newline, a semicolon, or the end of a file stream:

-
node1; node2; node3;
+
node1; node2; node3;
+

Values

KDL supports 4 data types:

Strings

-

It supports two different formats for string input: escaped and raw.

-
node "this\nhas\tescapes"
-other r"C:\Users\zkat\"
-

Both types of string can be multiline as-is, without a different syntax:

-
string "my
-multiline
-value"
-

And for raw strings, you can add any number of # after the r and the last " to -disambiguate literal " characters:

-
other-raw r#"hello"world"#
+

It supports three different formats for string input: identifiers, quoted, and raw.

+
node1 this-is-a-string
+node2 "this\nhas\tescapes"
+node3 #"C:\Users\zkat\raw\string"#
+
+

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 (""") followed immediately by a newline. Additionally, common +indentation shared with the line containing the closing quotes will be +stripped/dedented:

+
string """
+  my
+    multiline
+  value
+  """
+
+

Raw strings, which do not support \ 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} "[^/"]+""#
+
+

You can add any number of #s before and after the opening and +closing # to disambiguate literal closing #" sequences:

+
other-raw ##"hello#"world"##
+

Numbers

-

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.

-
num 1.234e-42
+
num 1.234e-42
+

And using the appropriate prefix, you can also enter hexadecimal, octal, and binary literals:

-
my-hex 0xdeadbeef
-my-octal 0o755
-my-binary 0b10101101
+
my-hex 0xdeadbeef
+my-octal 0o755
+my-binary 0b10101101
+

Finally, all numbers can have underscores to help readability:

-
bignum 1_000_000
+
bignum 1_000_000
+

Comments

KDL supports C-style comments, both line-based and multiline. Multiline comments can be nested.

-
// C style
-
-/*
-C style multiline
-*/
-
-tag /*foo=true*/ bar=false
-
-/*/*
-hello
-*/*/
+
// C style
+
+/*
+C style multiline
+*/
+
+tag /*foo=#true*/ bar=#false
+
+/*/*
+hello
+*/*/
+

On top of that, KDL supports /- "slashdash" comments, which can be used to -comment out individual nodes, arguments, or children:

-
// 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
-}
+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
+}
+// The above is equivalent to:
+mynode "not commented"
+

Type Annotations

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
+}
+

More Details

-
// 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
-
-
-

Implementations

- -

Editor Support

- -
-
-

Design and Discussion

-

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
+

Design Principles

    -
  1. Maintainability
  2. +
  3. Human Maintainability
  4. Flexibility
  5. -
  6. Cognitive simplicity and Learnability
  7. +
  8. Cognitive Simplicity and Learnability
  9. Ease of de/serialization
  10. Ease of implementation
@@ -241,37 +495,52 @@ KDL that, even if not entirely idiomatic, is still valid and fits into the data models of the other two languages:

-
+

FAQ

How do you pronounce KDL?

Same as "cuddle".

Why yet another document language?

Because nothing out there felt quite right. The closest one I found was SDLang, but that had some design choices I disagreed with.

+

Ok, then, why not SDLang?

-

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:

Have you seen that one XKCD comic about standards?

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.

What about TOML?

It nests very poorly. It doesn't fare well with large files.

What about XML?

@@ -321,7 +591,6 @@ fragments.

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.

-
- +
diff --git a/styles/global.css b/styles/global.css index d8464bb..703ef3c 100644 --- a/styles/global.css +++ b/styles/global.css @@ -1,4 +1,6 @@ -/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */ +/*! tailwindcss v2.2.19 | MIT License | https://tailwindcss.com */ + +/*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */ /* Document @@ -10,8 +12,8 @@ Use a better box model (opinionated). */ *, -*::before, -*::after { +::before, +::after { box-sizing: border-box; } @@ -19,7 +21,7 @@ Use a better box model (opinionated). Use a more readable tab size (opinionated). */ -:root { +html { -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4; @@ -209,6 +211,11 @@ button, Remove the inner border and padding in Firefox. */ +::-moz-focus-inner { + border-style: none; + padding: 0; +} + /** Restore the focus styles unset by the previous rule. */ @@ -238,20 +245,39 @@ progress { Correct the cursor style of increment and decrement buttons in Safari. */ +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + /** 1. Correct the odd appearance in Chrome and Safari. 2. Correct the outline style in Safari. */ +[type='search'] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + /** Remove the inner padding in Chrome and Safari on macOS. */ +::-webkit-search-decoration { + -webkit-appearance: none; +} + /** 1. Correct the inability to style clickable types in iOS and Safari. 2. Change font properties to 'inherit' in Safari. */ +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + /* Interactive =========== @@ -296,16 +322,6 @@ button { background-image: none; } -/** - * Work around a Firefox/IE bug where the transparent `button` background - * results in a loss of the default `button` focus styles. - */ - -button:focus { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; -} - fieldset { margin: 0; padding: 0; @@ -376,7 +392,7 @@ body { box-sizing: border-box; /* 1 */ border-width: 0; /* 2 */ border-style: solid; /* 2 */ - border-color: #e5e7eb; /* 2 */ + border-color: currentColor; /* 2 */ } /* @@ -406,15 +422,13 @@ textarea { } input::-moz-placeholder, textarea::-moz-placeholder { - color: #9ca3af; -} - -input:-ms-input-placeholder, textarea:-ms-input-placeholder { + opacity: 1; color: #9ca3af; } input::placeholder, textarea::placeholder { + opacity: 1; color: #9ca3af; } @@ -422,6 +436,14 @@ button { cursor: pointer; } +/** + * Override legacy focus reset from Normalize with modern Firefox focus styles. + * + * This is actually an improvement over the new defaults in Firefox in our testing, + * as it triggers the better focus styles even for links, which still use a dotted + * outline in Firefox by default. + */ + table { border-collapse: collapse; } @@ -479,11 +501,20 @@ samp { } /** - * Make replaced elements `display: block` by default as that's - * the behavior you want almost all of the time. Inspired by - * CSS Remedy, with `svg` added as well. + * 1. Make replaced elements `display: block` by default as that's + * the behavior you want almost all of the time. Inspired by + * CSS Remedy, with `svg` added as well. * - * https://github.com/mozdevs/cssremedy/issues/14 + * https://github.com/mozdevs/cssremedy/issues/14 + * + * 2. Add `vertical-align: middle` to align replaced elements more + * sensibly by default when overriding `display` by adding a + * utility like `inline`. + * + * This can trigger a poorly considered linting error in some + * tools but is included by design. + * + * https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210 */ img, @@ -494,13 +525,13 @@ audio, iframe, embed, object { - display: block; - vertical-align: middle; + display: block; /* 1 */ + vertical-align: middle; /* 2 */ } /** * Constrain images and videos to the parent width and preserve - * their instrinsic aspect ratio. + * their intrinsic aspect ratio. * * https://github.com/mozdevs/cssremedy/issues/14 */ @@ -511,6 +542,20 @@ video { height: auto; } +/** + * Ensure the default browser behavior of the `hidden` attribute. + */ + +*, ::before, ::after { + --tw-border-opacity: 1; + border-color: rgba(229, 231, 235, var(--tw-border-opacity)); +} + +.mx-auto { + margin-left: auto; + margin-right: auto; +} + .table { display: table; } @@ -523,56 +568,12 @@ video { height: 10rem; } -.mx-auto { - margin-left: auto; - margin-right: auto; -} - -.px-4 { - padding-left: 1rem; - padding-right: 1rem; -} - -.pb-10 { - padding-bottom: 2.5rem; -} - -.pt-20 { - padding-top: 5rem; -} - -* { - --tw-shadow: 0 0 #0000; -} - -* { - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgba(59, 130, 246, 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; -} - -@-webkit-keyframes spin { - to { - transform: rotate(360deg); - } -} - @keyframes spin { to { transform: rotate(360deg); } } -@-webkit-keyframes ping { - 75%, 100% { - transform: scale(2); - opacity: 0; - } -} - @keyframes ping { 75%, 100% { transform: scale(2); @@ -580,46 +581,63 @@ video { } } -@-webkit-keyframes pulse { - 50% { - opacity: .5; - } -} - @keyframes pulse { 50% { opacity: .5; } } -@-webkit-keyframes bounce { - 0%, 100% { - transform: translateY(-25%); - -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1); - animation-timing-function: cubic-bezier(0.8,0,1,1); - } - - 50% { - transform: none; - -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1); - animation-timing-function: cubic-bezier(0,0,0.2,1); - } -} - @keyframes bounce { 0%, 100% { transform: translateY(-25%); - -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1); - animation-timing-function: cubic-bezier(0.8,0,1,1); + animation-timing-function: cubic-bezier(0.8,0,1,1); } 50% { transform: none; - -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1); - animation-timing-function: cubic-bezier(0,0,0.2,1); + animation-timing-function: cubic-bezier(0,0,0.2,1); } } +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.pt-20 { + padding-top: 5rem; +} + +.pb-10 { + padding-bottom: 2.5rem; +} + +*, ::before, ::after { + --tw-shadow: 0 0 #0000; +} + +*, ::before, ::after { + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgba(59, 130, 246, 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; +} + +.filter { + --tw-blur: var(--tw-empty,/*!*/ /*!*/); + --tw-brightness: var(--tw-empty,/*!*/ /*!*/); + --tw-contrast: var(--tw-empty,/*!*/ /*!*/); + --tw-grayscale: var(--tw-empty,/*!*/ /*!*/); + --tw-hue-rotate: var(--tw-empty,/*!*/ /*!*/); + --tw-invert: var(--tw-empty,/*!*/ /*!*/); + --tw-saturate: var(--tw-empty,/*!*/ /*!*/); + --tw-sepia: var(--tw-empty,/*!*/ /*!*/); + --tw-drop-shadow: var(--tw-empty,/*!*/ /*!*/); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + .kdl-section { color: #374151; max-width: 65ch;