v1.0.0
2018年7月10日公開 – テキストバージョン

TOML v0.5.0

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

Tom Preston-Werner著。

バージョン0.5.0の時点で、TOMLは非常に安定していると見なすべきです。目標は、バージョン1.0.0が(可能な限り)バージョン0.5.0と後方互換性を持つことです。すべての実装は、0.5.0互換になることを強く推奨します。そうすれば、1.0.0への移行が簡単になります。

目的

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

# This is a TOML document.

title = "TOML Example"

[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00 # First class dates

[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true

[servers]

  # Indentation (tabs and/or spaces) is allowed but not required
  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

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

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

# Line breaks are OK when inside arrays
hosts = [
  "alpha",
  "omega"
]

仕様

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

コメント

ハッシュ記号は、行の残りの部分をコメントとしてマークします。

# This is a full-line comment
key = "value" # This is a comment at the end of a line

キー/値のペア

TOMLドキュメントの主要な構成要素は、キー/値のペアです。

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

key = "value"

値は、次の型である必要があります:文字列、整数、浮動小数点数、真偽値、日時、配列、またはインラインテーブル。未指定の値は無効です。

key = # INVALID

キー

キーは、ベア、引用符付き、またはドット付きのいずれかです。

ベアキーには、ASCII文字、ASCII数字、アンダースコア、およびダッシュ(A-Za-z0-9_-)のみを含めることができます。ベアキーはASCII数字のみで構成することもできます(例:1234)が、常に文字列として解釈されることに注意してください。

key = "value"
bare_key = "value"
bare-key = "value"
1234 = "value"

引用符付きキーは、基本文字列またはリテラル文字列とまったく同じ規則に従い、より幅広いキー名を使用できます。最良のプラクティスは、絶対に必要な場合を除き、ベアキーを使用することです。

"127.0.0.1" = "value"
"character encoding" = "value"
"ʎǝʞ" = "value"
'key2' = "value"
'quoted "value"' = "value"

ベアキーは空であってはなりませんが、空の引用符付きキーは許可されています(ただし推奨されません)。

= "no key name"  # INVALID
"" = "blank"     # VALID but discouraged
'' = 'blank'     # VALID but discouraged

ドット付きキーは、ドットで結合されたベアキーまたは引用符付きキーのシーケンスです。これにより、同様のプロパティをグループ化できます。

name = "Orange"
physical.color = "orange"
physical.shape = "round"
site."google.com" = true

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

{
  "name": "Orange",
  "physical": {
    "color": "orange",
    "shape": "round"
  },
  "site": {
    "google.com": true
  }
}

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

キーを複数回定義することは無効です。

# DO NOT DO THIS
name = "Tom"
name = "Pradyun"

キーが直接定義されていない限り、それに書き込んだり、その中の名前に書き込んだりできます。

a.b.c = 1
a.d = 2
# THIS IS INVALID
a.b = 1
a.b.c = 2

文字列

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

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

str = "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つの引用符で囲まれており、改行を許可します。開始区切り文字の直後の改行はトリミングされます。その他すべての空白文字と改行文字はそのまま残ります。

str1 = """
Roses are red
Violets are blue"""

TOMLパーサーは、プラットフォームにとって意味のある改行に自由に正規化できます。

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

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

不要な空白を導入せずに長い文字列を記述するには、「行末バックスラッシュ」を使用します。行の最後の空白文字以外の文字が\の場合、次の空白文字以外の文字または閉じ区切り文字までのすべての空白(改行を含む)とともにトリミングされます。基本文字列に有効なすべてのエスケープシーケンスは、複数行の基本文字列にも有効です。

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

str2 = """
The quick brown \


  fox jumps over \
    the lazy dog."""

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

バックスラッシュと制御文字(U+0000〜U+001F、U+007F)を除き、任意のUnicode文字を使用できます。引用符は、その存在が早すぎる閉じ区切り文字を作成する場合を除き、エスケープする必要はありません。

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

リテラル文字列は、単一引用符で囲まれています。基本文字列と同様に、単一行に表示する必要があります

# 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エンコーディングを使用することをお勧めします。そのエンコーディングの処理は、アプリケーション固有になります。

整数

整数は整数です。正の数はプラス記号で始まる場合があります。負の数はマイナス記号で始まります。

int1 = +99
int2 = 42
int3 = 0
int4 = -17

大きな数値の場合は、数字の間にアンダースコアを使用して読みやすさを向上させることができます。各アンダースコアは、両側に少なくとも1つの数字で囲む必要があります。

int5 = 1_000
int6 = 5_349_221
int7 = 1_2_3_4_5     # VALID but discouraged

先頭のゼロは許可されていません。整数値-0+0は有効であり、プレフィックスのないゼロと同じです。

非負の整数値は、16進数、8進数、または2進数で表すこともできます。これらの形式では、(プレフィックスの後)先頭のゼロが許可されます。16進数値は大文字と小文字を区別しません。アンダースコアは数字の間で許可されています(ただし、プレフィックスと値の間ではありません)。

# hexadecimal with prefix `0x`
hex1 = 0xDEADBEEF
hex2 = 0xdeadbeef
hex3 = 0xdead_beef

# octal with prefix `0o`
oct1 = 0o01234567
oct2 = 0o755 # useful for Unix file permissions

# binary with prefix `0b`
bin1 = 0b11010110

64ビット(符号付きロング)範囲が予想されます(−9,223,372,036,854,775,808〜9,223,372,036,854,775,807)。

浮動小数点数

浮動小数点数は、IEEE 754 binary64値として実装する必要があります。

浮動小数点数は、整数部分(整数値と同じ規則に従います)の後に、小数部分と/または指数部分で構成されます。小数部分と指数部分の両方が存在する場合、小数部分は指数部分より前に記述する必要があります。

# fractional
flt1 = +1.0
flt2 = 3.1415
flt3 = -0.01

# exponent
flt4 = 5e+22
flt5 = 1e6
flt6 = -2E-2

# both
flt7 = 6.626e-34

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

指数部分は、E(大文字または小文字)とそれに続く整数部分(整数値と同じ規則に従います)です。

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

flt8 = 9_224_617.445_991_228_313

浮動小数点数値-0.0+0.0は有効であり、IEEE 754に従ってマッピングする必要があります。

特殊な浮動小数点数値を表現することもできます。それらは常に小文字です。

# infinity
sf1 = inf  # positive infinity
sf2 = +inf # positive infinity
sf3 = -inf # negative infinity

# not a number
sf4 = nan  # actual sNaN/qNaN encoding is implementation specific
sf5 = +nan # same as `nan`
sf6 = -nan # valid, actual encoding is implementation specific

真偽値

真偽値は、使用しているトークンと同じです。常に小文字。

bool1 = true
bool2 = false

オフセット付き日時

特定の時間を明確に表現するには、RFC 3339形式のオフセット付き日時を使用できます。

odt1 = 1979-05-27T07:32:00Z
odt2 = 1979-05-27T00:32:00-07:00
odt3 = 1979-05-27T00:32:00.999999-07:00

読みやすさを考慮して、日付と時間の間のT区切り文字をスペースに置き換えることができます(RFC 3339セクション5.6で許可されています)。

odt4 = 1979-05-27 07:32:00Z

小数秒の精度は実装固有ですが、少なくともミリ秒の精度が期待されます。値に実装がサポートできるよりも高い精度が含まれている場合は、追加の精度は切り捨てられ、丸められません。

ローカル日時

RFC 3339形式の日時からオフセットを省略した場合、オフセットやタイムゾーンに関係なく、指定された日時を表します。追加情報なしに、時間の瞬間に変換することはできません。必要に応じて、瞬間への変換は実装固有です。

ldt1 = 1979-05-27T07:32:00
ldt2 = 1979-05-27T00:32:00.999999

小数秒の精度は実装固有ですが、少なくともミリ秒の精度が期待されます。値に実装がサポートできるよりも高い精度が含まれている場合は、追加の精度は切り捨てられ、丸められません。

ローカル日付

RFC 3339形式の日時の日付部分のみを含める場合、オフセットやタイムゾーンに関係なく、その日全体を表します。

ld1 = 1979-05-27

ローカル時間

RFC 3339形式の日時の時間部分のみを含める場合、特定の日付、オフセット、またはタイムゾーンに関係なく、その時刻を表します。

lt1 = 07:32:00
lt2 = 00:32:00.999999

小数秒の精度は実装固有ですが、少なくともミリ秒の精度が期待されます。値に実装がサポートできるよりも高い精度が含まれている場合は、追加の精度は切り捨てられ、丸められません。

配列

配列は、中に値が入った角かっこです。空白は無視されます。要素はコンマで区切られます。データ型を混在させることはできません(文字列を定義するさまざまな方法は同じ型と見なす必要があり、異なる要素型を持つ配列も同様です)。

arr1 = [ 1, 2, 3 ]
arr2 = [ "red", "yellow", "green" ]
arr3 = [ [ 1, 2 ], [3, 4, 5] ]
arr4 = [ "all", 'strings', """are the same""", '''type''']
arr5 = [ [ 1, 2 ], ["a", "b", "c"] ]

arr6 = [ 1, 2.0 ] # INVALID

配列は複数行にすることもできます。末尾のコンマ(後続のコンマとも呼ばれます)は、配列の最後の値の後に使用できます。値の前と閉じ括弧の前に、任意の数の改行とコメントを含めることができます。

arr7 = [
  1, 2, 3
]

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

テーブル

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

[table]

その下と、次のテーブルまたはEOFまでの間には、そのテーブルのキー/値があります。テーブル内のキー/値ペアが特定の順序であることは保証されていません。

[table-1]
key1 = "some string"
key2 = 123

[table-2]
key1 = "another string"
key2 = 456

テーブルの名前付け規則は、キーの場合と同じです(上記のキーの定義を参照)。

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

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

{ "dog": { "tater.man": { "type": { "name": "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

空のテーブルは許可されており、その中にキー/値ペアはありません。

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

# DO NOT DO THIS

[a]
b = 1

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

[a]
b = 1

[a.b]
c = 2

インラインテーブル

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

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

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

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

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

[point]
x = 1
y = 2

[animal]
type.name = "pug"

テーブルの配列

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

[[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 = []

[[fruit]] # Not allowed

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

# 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 } ]

ファイル拡張子

TOMLファイルは、拡張子.tomlを使用する必要があります。

MIMEタイプ

インターネット経由でTOMLファイルを転送する場合、適切なMIMEタイプはapplication/tomlです。

他のフォーマットとの比較

いくつかの点で、TOMLはJSONと非常によく似ています。シンプルで、明確に定義されており、ユビキタスなデータ型に簡単にマッピングできます。JSONは、主にコンピュータプログラムによって読み書きされるデータをシリアライズするのに最適です。TOMLがJSONと異なる点は、人間が読み書きしやすいことを重視している点です。コメントはその良い例です。コメントは、あるプログラムから別のプログラムにデータを送信する場合には何の役にも立ちませんが、手動で編集する可能性のある構成ファイルでは非常に役立ちます。

YAML形式は、TOMLと同様に構成ファイル向けです。しかし、多くの目的において、YAMLは過度に複雑なソリューションです。TOMLはシンプルさを目指しており、それはYAML仕様には見られない目標です:http://www.yaml.org/spec/1.2/spec.html

INI形式も構成ファイルによく使用されます。ただし、この形式は標準化されておらず、通常は1つまたは2つ以上のレベルのネストを処理しません。

参加する

ドキュメント、バグレポート、プルリクエスト、その他すべての貢献を歓迎します!

Wiki

私たちは、次の項目をまとめた公式TOML Wikiを持っています。

  • TOMLを使用しているプロジェクト
  • 実装
  • バリデーター
  • TOMLデコーダーとエンコーダー向けの言語に依存しないテストスイート
  • エディターサポート
  • エンコーダー
  • コンバーター

リストを表示または追加したい場合は、ご覧ください。TOMLコミュニティの一員となっていただきありがとうございます!