v1.0.0
11/11/2014 日掲載 – テキスト版

TOML

トムの明瞭で最小の言語の意味。 (By Tom Preston Werner)

最新版はv0.3.1です。

注:この仕様はまだ固まっておらず、バージョン1.0になるまでは安定しない可能性があります。

訳注:2015-01-05時点のmasterのREADME.mdを元にしています。 最新のバージョンとは異なる可能性があります。 オリジナルの翻訳はgistで管理します。 https://gist.github.com/minoritea/acde44feae7127c89873

目的

TOMLは明瞭なセマンティクスを持ち、可読性の高い、ミニマルな設定ファイルフォーマットとなることを目的として作られています。TOMLは曖昧さなしに連想配列に変換できるよう設計されていて、 様々な言語上でそれらのデータ構造に展開することが出来ます。

# TOMLドキュメントの例です。

title = "TOML Example"

[owner]
name = "Lance Uppercut"
dob = 1979-05-27T07:32:00-08:00 # 日付は当然ファーストクラスです。
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true

[servers]

# タブもしくはスペースで自由にインデントできます。
[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"

[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"

[clients]
data = [ ["gamma", "delta"], [1, 2] ]

# 配列内の改行ももちろんOK!
hosts = [
"alpha",
"omega"
]

仕様

  • TOMLはケース・センシティブです
  • TOMLファイルはユニコード(UTF-8)でエンコードされている必要があります
  • 空白はタブ(0x09)もしくはスペース(0x20)のことです
  • 改行はLF(0x0A)もしくはCRLF(0x0D0A)です。

コメント

ハッシュ記号(#)に続けて改行までをコメントとします。

# 好きなようにコメントできます。
key = "value" # こんな感じで!

整数

整数は全ての数のことです(訳注:整数全体のことだと思われる)。正の数を表すときはプラス符号+を前につけても、つけなくても構いません。負の数の場合はマイナス符号-を前につけます。

+99
42
0
-17

整数の表記をゼロから始めることは出来ません。2進数、8進数、16進数の形式で表すことも出来ません。無限や非数を表すことも出来ません。期待される範囲としては、64bit(signed long)となります(−9,223,372,036,854,775,808 〜 9,223,372,036,854,775,807)。

小数

小数は整数部(プラス,マイナス符号をつけてもよい)と、それに続く小数部もしくは指数部から成ります。小数部と指数部の両方で表すことも出来ますが、その場合は小数部を指数部より前に置く必要があります。

# 小数表記
+1.0
3.1415
-0.01

# 指数表記
5e+22
1e6
-2E-2

# 複合
6.626e-34

小数部は小数点の後に数字をならべて表記します。

指数部はE(大文字小文字は問わない)の後に整数(プラス,マイナス符号をつけてもよい)で表記します。

期待される範囲は、64-bit(double)精度です。

ブーリアン

ブーリアン値はただのトークンです(いつも使っているやつです)。小文字のみとします。

true
false

日付

日付型はRFC 3339に準じます。

1979-05-27T07:32:00Z
1979-05-27T00:32:00-07:00
1979-05-27T00:32:00.999999-07:00

配列

配列は角括弧で囲まれたプリミティブ型の集まりです。空白は無視されます。各要素はカンマで区切られます。各データ型を混合させることは出来ません。

[ 1, 2, 3 ]
[ "red", "yellow", "green" ]
[ [ 1, 2 ], [3, 4, 5] ]
[ [ 1, 2 ], ["a", "b", "c"] ] # この書き方はOK
[ 1, 2.0 ] # 一つの配列に違う型を混合させるのはダメ

配列は複数行に書くことも出来ます。その場合空白に加えて改行も無視されます。閉じ括弧の前にカンマを書いても構いません。

key = [
1, 2, 3
]

key = [
1,
2, # OK
]

テーブル

テーブル(ハッシュテーブルや連想配列のことです)はキーと値のペアからなる集まりです。それは角括弧で囲まれたテーブル名が書かれた行から始まります。配列は必ず値として表記されるので、テーブルの角括弧と配列は簡単に区別することが出来ます。

[table]

ここに続いて、次のテーブルの開始か、ファイルの終わりまで、キーと値はこのテーブルに属します。等号=の左にキーを、右に値を置きます。キーと値の周りの空白は無視されます。キー、等号、値は同じ行に書く必要があります(ただし値のいくつかは改行を含むことも出来ます)。

キーに使える文字は空白、改行、=#.[]以外の文字です(訳注:テーブル名も同様)。

テーブル内のキーと値の各ペアの順番は保証されません。

[table]
key = "value"

ドット(.)がキーに使えないのは、ネストしたテーブルを表すのにドットを使うからです。各ドットで分割された部分の命名規則は上記のキーの命名規則に準じます。

[dog.tater]
type = "pug"

これは以下のJSONと同じ構造を表します:

{ "dog": { "tater": { "type": "pug" } } }

もし、上位のテーブルそのものを記述する必要がないのであれば、省略することも出来ます。

# [x] 省略可
# [x.y] これも可
# [x.y.z] これも省略可
[x.y.z.w] # ここから始めて構いません

空のテーブルは単純にキーと値のペアを書かかないことで作れます。

上位のテーブルの定義を省略した場合、後からそのテーブルの内容を書くことが出来ます(後から書くキーも定義されていない場合のみ)。

[a.b]
c = 1

[a]
d = 2

キーやテーブルを再定義することは出来ません。不正となります。

# やっちゃダメです

[a]
b = 1

[a]
c = 2
# ダメですってば

[a]
b = 1

[a.b]
c = 2

テーブル名、キーを空にすることは出来ません。

# 不正なTOMLです
[]
[a.]
[a..b]
[.b]
[.]
= "no key name" # ダメ

テーブルの配列

最後の型はテーブルの配列です。テーブル名を角括弧で二重に囲むことで表されます。二重角括弧で囲まれた同じテーブル名を持つテーブルは、配列の要素となります。テーブルは表記順に配列に挿入されます。配列内のキーと値のペアを持たないテーブルは空のテーブルとして扱われます。

[[products]]
name = "Hammer"
sku = 738594937

[[products]]

[[products]]
name = "Nail"
sku = 284758393
color = "gray"

これは以下のJSONと同じ構造を表します:

{
  "products": [
  { "name": "Hammer", "sku": 738594937 },
  { },
  { "name": "Nail", "sku": 284758393, "color": "gray" }
  ]
}

あなたはネストしたテーブルの配列を作ることも出来ます。その場合は、子テーブルにも二重角括弧表記を使ってください。それぞれのテーブルは、その上の最も近い場所に定義されている親テーブルの要素となる配列に属します。

[[fruit]]
name = "apple"

[fruit.physical]
color = "red"
shape = "round"

[[fruit.variety]]
name = "red delicious"

[[fruit.variety]]
name = "granny smith"

[[fruit]]
name = "banana"

[[fruit.variety]]
name = "plantain"

上記のTOMLは下記のJSONに置き換えることができます。

{
  "fruit": [
  {
    "name": "apple",
    "physical": {
      "color": "red",
      "shape": "round"
    },
    "variety": [
    { "name": "red delicious" },
    { "name": "granny smith" }
    ]
  },
  {
    "name": "banana",
    "variety": [
    { "name": "plantain" }
    ]
  }
  ]
}

既にテーブルの配列として定義されたテーブルの後に、同じ名前を持つ通常のテーブルを定義しようとした場合、パースする際にエラーとすべきです。

# 不正なTOMLドキュメント
[[fruit]]
name = "apple"

[[fruit.variety]]
name = "red delicious"

# このテーブルは上のテーブルの配列とコンフリクトを起こします
[fruit.variety]
name = "granny smith"

これって真面目な規格?

YES

なんで作ったの?

私達はきちんと人間が読める、曖昧さなしに連想配列に変換できるフォーマットを必要としていました。そしてYAMLの仕様書は80ページもあって論外だと思ったのです。JSON?検討すらしていません。理由はあなたも分かってるでしょう?

いいね、使ってみよう

でしょでしょ?もしよければプルリク送ってください。もしくはパーサを書くとか。チャレンジしてみて!

実装

パーサ

もしパーサを作ったのならここに追加してプルリク送ってください。それと、パーサのREADMEには、サポートするTOMLのバージョンをgitのタグかハッシュの形式で書くようお願いします。

バリデータ

言語によらないデコーダとエンコーダのテストスイート

エディタ・サポート

エンコーダ

コンバータ