😽

新時代のデータ表現!?ドキュメント言語『KDL』

2024/03/18に公開

Zellijをカスタマイズしようとしたら、カスタマイズにKDLという言語を使っていたので、軽くその使い方をまとめようと思います。

https://kdl.dev/

引用はすべて 公式サイトkdl.dev) にあるものです。翻訳も付けています。

KDLとは?

KDL is a small, pleasing document language with xml-like semantics that looks like you're invoking a bunch of CLI commands!

KDLはXMLのような書き方をする、小さくて快適なドキュメント言語であり、まるでCLIコマンドを呼び出しているように感じるでしょう!

KDLはまるでCLIコマンドのように(?)データを表現することができます。

KDL is not 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.

KDLはマークアップ言語ではない。XMLやHTMLなどの特別なタグをもののほうが「マークアップ」に適しているだろうが、KDLは文書のデータ表現をもっと厳格に行いたいとき役に立つだろう。

つまり、KDLは「マークアップ言語」ではなくあくまでも「ドキュメント言語」というわけですね!(既視感[1])
発音はcuddleと同じで「カドル」[kʌ́dl] だそうです。

KDLの基礎文法

例えば、package.jsonのような内容を書くと、このような感じになります[2]

package {
  name "example"
  version "0.0.1"

  dependencies {
    astro "^4.5.5"
    prettier "^3.2.5" dev=true
  }

  scripts {
    dev "astro dev"
    build "astro build"
    format r#"
      prettier --write --plugin-search-dir=./ src/
    "#
  }
}

ノード (キー&値&プロパティ)

KDLはキープロパティという3つの要素を含む、ノードで構成されています。

    lodash "^3.2.1" optional=true alias="underscore"
    └────┘ └──────┘ └───────────┘ └────────────────┘
      key    value     property        property
※値とプロパティはつけてもつけなくてもいい

複数の値や

prime-numbers 2 3 5 7

匿名ノードも作れます。

node

さらに、順番バラバラでもOK

foo bar=true "baz" quux=false 1 2 3

:=でキーと値を結ぶJSON YAML TOMLとは違い、 (スペース)で組み合わせを表現します。
また、プロパティを書くこともできて柔軟性が高くなっています。

入れ子

入れ子にも対応しています。

contents {
  section "First section" {
    paragraph "This is the first paragraph"
    paragraph "This is the second paragraph"
  }
}

基本のデータ型

  • String ... "abc"
  • Number ... 0, 1.5, -3, 1.234e-42, 0b100111010, 1_100_111
    (指数表記、2,8,16進数、数字の途中の区切りに対応)
  • Bool ... true, false
  • Null ... null

文字列に関しては

// 普通の文字列でも改行できる
more-than-one-line-string "aaa
bbb"
// 
raw-string r"C:\User\kdl\"
// `#`で囲むと`"`を使える
other-raw r#" "kdl" is perfect "#

まあここらへんはRustと同じ

ある程度自由な名前付け

下のは全部有効なKDLです。

// 名前に記号OK
foo123~!@#$%^&* "うぉぉぉ"

// 全角もOK
ノード お名前="☜(゚ヮ゚☜)"

// 絵文字含むUnicodeに対応
smile "😁"

// もし必要なら、ノードも`"`でくくれる
"123abc" "1.2.3" "!!!!!"=true

Playgroundがあるので、気になるものがあったら試してみてください

コメント

C-styleの一行コメント、複数行コメント、

// C style

/*
C style multiline
*/

tag /*foo=true*/ bar=false

そして、独自の「スラッシュダッシュ」コメント。
KDL最大の特徴とも言えるコメントです。

// `/-`というコメントを使うと、あとに続くノード全体をコメント化することができる
// 複数行でも最初だけつければいいから楽ちん
/-mynode "foo" key=1 {
  a
  b
  c
}

⇧は全部コメント

プロパティだけコメントというのも可能です。

mynode /-"commented" "not commented" /-key="value" {
  a
  b
}
// どっちも同じ
mynode "not commented" {
  a
  b
}

型注釈

あと、型注釈もできます。

numbers (u8)10 (i32)20 myfloat=(f32)1.5 {
  (uuid)"123e4567-e89b-12d3-a456-426614174000"
  (date)"2021-02-03"
  filter=(regex)r"$\d+"
}

そんなに強制力はありませんが。

なぜKDL?

Because nothing out there felt quite right.

なぜなら、今あるものは何一つしっくりこなかったからだ。

らしいです。

JSONと比較

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.

JSONは素晴らしいシリアライズ言語だが、人間が使うには難しすぎる。それは、特殊で厳密な構文と、コメントのサポートの欠如が原因だ。

たしかに、JSONはキーに全て"を付ける必要があったり、コメントがかけなかったりで大変ですよね。知名度だけはものすごいけど
JSONは厳密だからいいんだよ

YAMLと比較

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.

YAMLは広く使われている素晴らしい言語である。ノードベース(XMLやHTMLのような)のKDLとは異なり、マップと配列のデータ構造に基づいており、場合によってはより簡単なシリアライズ体験を提供できるだろう。

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.
同時に、YAMLは書き込まれたデータがどのような型なのかあいまいなことがある。非常に大きな YAMLファイルが管理不可能になる持続的な問題もある。

KDL is designed to avoid these particular pitfalls by always being explicit about types, and having clearly-delimited scope
KDLは、型について常に明示的であること、スコープが明確に区切られていることによって、こうした特定の落とし穴を避けるように設計されている。

Syntax errors are easier to catch, and large files are (hopefully!) much more manageable.
構文エラーも見つけやすくなり、大きなファイルも(うまくいけば!)管理しやすくなる。

YAMLは厳格なインデントがめんどくさい。

TOMLと比較

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

入れ子が非常にダメ。大きいファイルには向いてない。

入れ子がダメ、それはほんとうにそう

XMLと比較

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.

XMLは実に素晴らしいもので、長い間、多くの業界でデータ交換の標準として使われてきた。同時に、XMLは非常に冗長であることが知られており、編集にはマッチするタグを書く(そして更新する)必要がある。

XMLは冗長すぎる。以上!!!

さいごに

ちょっと構文がゆるすぎてJSONの代わりにはならなさそうだけど、YAMLやTOMLの代わりにはなりそうですね。今後に期待ですね。

If you use KDL, syntax errors are easier to catch, and large files are (hopefully!) much more manageable.
KDLを使えば、構文エラーも見つけやすくなり、大きなファイルも(うまくいけば!)管理しやすくなるだろう。


これを採用しようと思ったZellij、勇気あるぞ。

脚注
  1. 「YAML: YAML Ain't Markup Language™」 ↩︎

  2. まだZennのハイライトがKDLに対応していないので、今の段階ではrustのハイライトを当てています。
    r#"..."#という書き方をするのがrustだけだったので。(というかKDL自体Rustの書き方をまねした) ↩︎

Discussion