v1.0.0
2015/2/12公開 – テキスト版

TOML v0.4.0

Tom's Obvious, Minimal Language(トムの明快で最小限の言語)

By Tom Preston-Werner.

注意:この仕様はまだ大幅に変更されています。1.0とマークされるまでは、不安定であると想定して対応する必要があります。

目標

TOMLは、明確なセマンティクスにより読みやすい、最小限の構成ファイル形式を目指しています。TOMLはハッシュテーブルに明確に対応するように設計されています。TOMLは、さまざまな言語のデータ構造に簡単に解析できる必要があります。

仕様

  • TOMLは大文字と小文字を区別します。
  • TOMLファイルには、UTF-8エンコードされたUnicode文字のみを含める必要があります。
  • 空白文字は、タブ(0x09)またはスペース(0x20)を意味します。
  • 改行は、LF(0x0A)またはCRLF(0x0D0A)を意味します。

コメント

ハッシュ記号を使って意見を述べましょう。ハッシュ記号から行末までがコメントになります。

# I am a comment. Hear me roar. Roar.
key = "value" # Yeah, you can do this.

文字列

文字列を表現する方法は、基本、複数行基本、リテラル、複数行リテラルの4つがあります。すべての文字列には、有効なUTF-8文字のみを含める必要があります。

基本文字列は、引用符で囲まれています。エスケープする必要がある文字(引用符、バックスラッシュ、制御文字(U+0000〜U+001F))を除き、任意のUnicode文字を使用できます。

"I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."

便宜上、一部の一般的な文字にはコンパクトなエスケープシーケンスがあります。

\b         - backspace       (U+0008)
\t         - tab             (U+0009)
\n         - linefeed        (U+000A)
\f         - form feed       (U+000C)
\r         - carriage return (U+000D)
\"         - quote           (U+0022)
\\         - backslash       (U+005C)
\uXXXX     - unicode         (U+XXXX)
\UXXXXXXXX - unicode         (U+XXXXXXXX)

任意のUnicode文字を、\uXXXXまたは\UXXXXXXXX形式でエスケープできます。エスケープコードは、有効なUnicode スカラー値である必要があります。

上記にリストされていない他のすべてのエスケープシーケンスは予約されており、使用するとTOMLはエラーを生成する必要があります。

テキストの一節(例:翻訳ファイル)を表現したり、非常に長い文字列を複数行に分割したりする必要がある場合があります。TOMLはこれを簡単にします。複数行基本文字列は、両側に3つの引用符で囲まれ、改行が許可されています。開始デリミターの直後の改行は削除されます。他のすべての空白文字と改行文字はそのまま残ります。

key1 = """
Roses are red
Violets are blue"""

TOMLパーサーは、プラットフォームにとって意味のあるものに改行を正規化しても構いません。

# On a Unix system, the above multi-line string will most likely be the same as:
key2 = "Roses are red\nViolets are blue"

# On a Windows system, it will most likely be equivalent to:
key3 = "Roses are red\r\nViolets are blue"

余分な空白文字を導入せずに長い文字列を記述するには、行末を\で終了します。\は、次の空白文字以外の文字または終了デリミターまでのすべての空白文字(改行を含む)とともに削除されます。開始デリミターの後の最初の文字がバックスラッシュと改行の場合、それらは両方とも、次の空白文字以外の文字または終了デリミターまでのすべての空白文字と改行とともに削除されます。基本文字列に有効なすべてのエスケープシーケンスは、複数行基本文字列にも有効です。

# The following strings are byte-for-byte equivalent:
key1 = "The quick brown fox jumps over the lazy dog."

key2 = """
The quick brown \


  fox jumps over \
    the lazy dog."""

key3 = """\
       The quick brown \
       fox jumps over \
       the lazy dog.\
       """

エスケープする必要がある文字(バックスラッシュと制御文字(U+0000〜U+001F))を除き、任意のUnicode文字を使用できます。引用符は、その存在が時期尚早な終了デリミターを作成しない限り、エスケープする必要はありません。

Windowsパスまたは正規表現を頻繁に指定する場合、バックスラッシュをエスケープする必要があるため、すぐに面倒でエラーが発生しやすくなります。これを支援するために、TOMLはエスケープがまったく許可されていないリテラル文字列をサポートしています。リテラル文字列は、単一引用符で囲まれています。基本文字列と同様に、1行で表示する必要があります。

# What you see is what you get.
winpath  = 'C:\Users\nodejs\templates'
winpath2 = '\\ServerX\admin$\system32\'
quoted   = 'Tom "Dubs" Preston-Werner'
regex    = '<\i\c*\s*>'

エスケープがないため、単一引用符で囲まれたリテラル文字列の中に単一引用符を記述する方法はありません。幸いなことに、TOMLはこの問題を解決する複数行バージョンのリテラル文字列をサポートしています。複数行リテラル文字列は、両側に3つの単一引用符で囲まれ、改行が許可されています。リテラル文字列と同様に、エスケープは一切ありません。開始デリミターの直後の改行は削除されます。デリミター間の他のすべてのコンテンツは、変更なしでそのまま解釈されます。

regex2 = '''I [dw]on't need \d{2} apples'''
lines  = '''
The first newline is
trimmed in raw strings.
   All other whitespace
   is preserved.
'''

バイナリデータの場合は、Base64またはその他の適切なASCIIまたはUTF-8エンコーディングを使用することをお勧めします。そのエンコーディングの処理は、アプリケーション固有になります。

整数

整数は整数です。正の数の場合はプラス記号を付けることができます。負の数の場合はマイナス記号を付けます。

+99
42
0
-17

大きな数の場合は、読みやすくするためにアンダースコアを使用できます。各アンダースコアは、少なくとも1つの数字で囲む必要があります。

1_000
5_349_221
1_2_3_4_5     # valid but inadvisable

先頭のゼロは許可されていません。16進数、8進数、および2進数形式は許可されていません。一連の数字として表現できない「無限大」や「非数」などの値は許可されていません。

64ビット(符号付き長整数)の範囲が予想されます(-9,223,372,036,854,775,808〜9,223,372,036,854,775,807)。

浮動小数点数

浮動小数点数は、整数部分(プラスまたはマイナス記号を付けることができる)、それに続く小数部分および/または指数部分で構成されます。小数部分と指数部分の両方が存在する場合、小数部分は指数部分より前に記述する必要があります。

# fractional
+1.0
3.1415
-0.01

# exponent
5e+22
1e6
-2E-2

# both
6.626e-34

小数部分は、小数点とそれに続く1つ以上の数字です。

指数部分は、E(大文字または小文字)とそれに続く整数部分(プラスまたはマイナス記号を付けることができる)です。

整数と同様に、読みやすくするためにアンダースコアを使用できます。各アンダースコアは、少なくとも1つの数字で囲む必要があります。

9_224_617.445_991_228_313
1e1_000

64ビット(倍精度)が予想されます。

真偽値

ブール値は、使い慣れているトークンです。常に小文字です。

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] ]
[ "all", 'strings', """are the same""", '''type'''] # this is ok
[ [ 1, 2 ], ["a", "b", "c"] ] # this is ok
[ 1, 2.0 ] # note: this is NOT ok

配列は複数行にすることもできます。したがって、空白を無視するだけでなく、配列は角かっこ間の改行も無視します。終端のコンマは、右角かっこの前で構いません。

key = [
  1, 2, 3
]

key = [
  1,
  2, # this is ok
]

テーブル

テーブル(ハッシュテーブルまたは辞書とも呼ばれます)は、キーと値のペアのコレクションです。これらは、1行に角かっこで囲まれて表示されます。配列は値としてのみ存在するため、配列と区別できます。

[table]

その下から、次のテーブルまたはEOFまでは、そのテーブルのキーと値です。キーは等号の左側にあり、値は右側にあります。キー名と値の周りの空白は無視されます。キー、等号、および値は同じ行にある必要があります(ただし、一部の値は複数行に分割できます)。

キーは、ベアまたは引用符付きのいずれかです。ベアキーには、文字、数字、アンダースコア、およびダッシュ(A-Za-z0-9_-)のみを含めることができます。引用符付きキーは、基本文字列とまったく同じルールに従い、はるかに広範なキー名を使用できます。ベストプラクティスは、どうしても必要な場合を除いて、ベアキーを使用することです。

テーブル内のキーと値のペアは、特定の順序で並んでいることは保証されていません。

[table]
key = "value"
bare_key = "value"
bare-key = "value"

"127.0.0.1" = "value"
"character encoding" = "value"
"ʎǝʞ" = "value"

ドットは、ドットがネストされたテーブルを示すために使用されるため、ベアキーでは禁止されています。ドットで区切られた各部分の命名規則は、キーの場合と同じです(上記を参照)。

[dog."tater.man"]
type = "pug"

JSONの世界では、次の構造になります。

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

ドットで区切られた部分の周りの空白は無視されますが、ベストプラクティスは、余分な空白を使用しないことです。

[a.b.c]          # this is best practice
[ d.e.f ]        # same as [d.e.f]
[ g .  h  . i ]  # same as [g.h.i]
[ j . "ʞ" . l ]  # same as [j."ʞ".l]

必要に応じて、すべてのスーパテーブルを指定する必要はありません。TOMLは、それを実行する方法を知っています。

# [x] you
# [x.y] don't
# [x.y.z] need these
[x.y.z.w] # for this to work

空のテーブルは許可されており、単にキーと値のペアが含まれていません。

スーパテーブルが直接定義されておらず、特定のキーを定義していない限り、それに書き込むことができます。

[a.b]
c = 1

[a]
d = 2

キーまたはテーブルを複数回定義することはできません。そうすることは無効です。

# DO NOT DO THIS

[a]
b = 1

[a]
c = 2
# DO NOT DO THIS EITHER

[a]
b = 1

[a.b]
c = 2

すべてのテーブル名とキーは空でない必要があります。

# NOT VALID TOML
[]
[a.]
[a..b]
[.b]
[.]
 = "no key name" # not allowed

インラインテーブル

インラインテーブルは、テーブルを表現するためのよりコンパクトな構文を提供します。これらは、それ以外の場合はすぐに冗長になる可能性のあるグループ化されたデータに特に役立ちます。インラインテーブルは、中かっこ{}で囲まれています。中かっこ内には、ゼロ個以上のコンマ区切りのキーと値のペアを表示できます。キーと値のペアは、標準テーブルのキーと値のペアと同じ形式を取ります。インラインテーブルを含む、すべての値型が許可されています。

インラインテーブルは、1行で表示されることを目的としています。値の中で有効でない限り、中かっこの間に改行は許可されていません。それでも、インラインテーブルを複数行に分割することは強くお勧めしません。この欲求に駆られていることに気づいた場合は、標準テーブルを使用する必要があることを意味します。

name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 }

上記のインラインテーブルは、次の標準テーブル定義と同じです。

[name]
first = "Tom"
last = "Preston-Werner"

[point]
x = 1
y = 2

テーブルの配列

まだ表現されていない最後の型は、テーブルの配列です。これらは、二重角かっこで囲まれたテーブル名を使用して表現できます。同じ二重角かっこで囲まれた名前を持つ各テーブルは、配列の要素になります。テーブルは、出現した順序で挿入されます。キーと値のペアのない二重角かっこで囲まれたテーブルは、空のテーブルと見なされます。

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

すでに確立された配列と同じ名前で通常のテーブルを定義しようとすると、解析時にエラーが発生する必要があります。

# INVALID TOML DOC
[[fruit]]
  name = "apple"

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

  # This table conflicts with the previous table
  [fruit.variety]
    name = "granny smith"

必要に応じて、インラインテーブルも使用できます

points = [ { x = 1, y = 2, z = 3 },
           { x = 7, y = 8, z = 9 },
           { x = 2, y = 4, z = 8 } ]

マジで?

はい。

なぜ?

ハッシュテーブルに明確にマッピングされ、人間が判読できる適切な形式が必要なため、YAML仕様は80ページほどで、私を激怒させるからです。いいえ、JSONはカウントされません。理由はわかります。

ああ、その通りだ

そうだ。手伝いたい?プルリクエストを送ってください。またはパーサーを作成してください。勇敢になれ。

TOMLを使用しているプロジェクト

  • Cargo - Rust言語のパッケージマネージャー。
  • InfluxDB - 分散時系列データベース。
  • Heka - Mozillaによるストリーム処理システム。
  • Hugo - Goの静的サイトジェネレーター。

実装

実装がある場合は、このリストに追加するプルリクエストを送信してください。パーサーがサポートするコミットSHA1またはバージョンタグをReadmeに記載してください。

バリデーター

TOMLデコーダーとエンコーダーのための言語非依存テストスイート

エディターサポート

エンコーダー

コンバーター