v1.0.0
2021年1月11日公開 – テキストバージョン

TOML v1.0.0

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

作成者: Tom Preston-Werner, Pradyun Gedam, 他

目的

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

仕様

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

コメント

ハッシュ記号は、文字列内を除き、行の残りをコメントとしてマークします。

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

タブ以外の制御文字(U+0000からU+0008、U+000AからU+001F、U+007F)は、コメントでは許可されていません。

キー/値ペア

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

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

key = "value"

値は、次のいずれかの型である必要があります。

指定されていない値は無効です。

key = # INVALID

キー/値ペアの後には、改行(またはEOF)が必要です。(例外については、インラインテーブルを参照してください。)

first = "Tom" last = "Preston-Werner" # 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
  }
}

ドット付きキーで定義されるテーブルの詳細については、以下のテーブルセクションを参照してください。

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

fruit.name = "banana"     # this is best practice
fruit. color = "yellow"    # same as fruit.color
fruit . flavor = "banana"   # same as fruit.flavor

インデントは空白として扱われ、無視されます。

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

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

ベアキーとクォートされたキーは同等であることに注意してください。

# THIS WILL NOT WORK
spelling = "favorite"
"spelling" = "favourite"

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

# This makes the key "fruit" into a table.
fruit.apple.smooth = true

# So then you can add to the table "fruit" like so:
fruit.orange = 2
# THE FOLLOWING IS INVALID

# This defines the value of fruit.apple to be an integer.
fruit.apple = 1

# But then this treats fruit.apple like it's a table.
# You can't turn an integer into a table.
fruit.apple.smooth = true

ドット付きキーを順不同で定義することはお勧めしません。

# VALID BUT DISCOURAGED

apple.type = "fruit"
orange.type = "fruit"

apple.skin = "thin"
orange.skin = "thick"

apple.color = "red"
orange.color = "orange"
# RECOMMENDED

apple.type = "fruit"
apple.skin = "thin"
apple.color = "red"

orange.type = "fruit"
orange.skin = "thick"
orange.color = "orange"

ベアキーはASCII整数のみで構成できるため、浮動小数点数のように見えるが2つの部分からなるドット付きキーを作成できます。正当な理由がない限り、これを行わないでください(おそらくありません)。

3.14159 = "pi"

上記のTOMLは、次のJSONにマッピングされます。

{ "3": { "14159": "pi" } }

文字列

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

基本文字列は、引用符(")で囲まれています。エスケープする必要がある文字(引用符、バックスラッシュ、およびタブ以外の制御文字(U+0000からU+0008、U+000Aから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+0008、U+000B、U+000C、U+000EからU+001F、U+007F))を除くすべてのUnicode文字を使用できます。

複数行基本文字列内の任意の場所に、引用符または2つの隣接する引用符を記述できます。区切り文字のすぐ内側に記述することもできます。

str4 = """Here are two quotation marks: "". Simple enough."""
# str5 = """Here are three quotation marks: """."""  # INVALID
str5 = """Here are three quotation marks: ""\"."""
str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""

# "This," she said, "is just a pointless statement."
str7 = """"This," she said, "is just a pointless statement.""""

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

複数行リテラル文字列内の任意の場所に1つまたは2つの一重引用符を記述できますが、3つ以上の一重引用符のシーケンスは許可されていません。

quot15 = '''Here are fifteen quotation marks: """""""""""""""'''

# apos15 = '''Here are fifteen apostrophes: ''''''''''''''''''  # INVALID
apos15 = "Here are fifteen apostrophes: '''''''''''''''"

# 'That,' she said, 'is still pointless.'
str = ''''That,' she said, 'is still pointless.''''

タブ以外の制御文字は、リテラル文字列では許可されていません。したがって、バイナリデータの場合、Base64またはその他の適切なASCIIまたはUTF-8エンコーディングを使用することをお勧めします。そのエンコーディングの処理はアプリケーション固有です。

整数

整数は整数です。正の数値には、プラス記号を付けることができます。負の数値には、マイナス記号が付けられます。

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

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

int5 = 1_000
int6 = 5_349_221
int7 = 53_49_221  # Indian number system grouping
int8 = 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ビット符号付き整数(-2^63から2^63-1)が受け入れられ、ロスレスで処理される必要があります。整数をロスレスで表現できない場合は、エラーをスローする必要があります。

浮動小数点数

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

浮動小数点数は、整数部(10進整数値と同じ規則に従う)と、小数部または指数部(あるいはその両方)で構成されます。小数部と指数部の両方が存在する場合、小数部は指数部の前に置く必要があります。

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

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

# both
flt7 = 6.626e-34

小数部は、小数点の後に1つ以上の数字が続きます。

指数部は、E(大文字または小文字)の後に整数部が続きます(10進整数値と同じ規則に従いますが、先行ゼロを含めることができます)。

小数点を使用する場合は、両側に少なくとも1つの数字で囲む必要があります。

# INVALID FLOATS
invalid_float_1 = .7
invalid_float_2 = 7.
invalid_float_3 = 3.e+20

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

flt8 = 224_617.445_991_228

浮動小数点数值-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

ミリ秒の精度は必須です。小数秒のさらなる精度は実装固有です。値に実装がサポートできるよりも高い精度が含まれている場合、追加の精度は丸めずに切り捨てる必要があります。

配列

配列は、値が内部にある角かっこです。空白は無視されます。要素はコンマで区切られます。配列には、キー/値ペアで許可されているのと同じデータ型の値を含めることができます。異なる型の値を混在させることができます。

integers = [ 1, 2, 3 ]
colors = [ "red", "yellow", "green" ]
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
string_array = [ "all", 'strings', """are the same""", '''type''' ]

# Mixed-type arrays are allowed
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
contributors = [
  "Foo Bar <foo@example.com>",
  { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
]

配列は複数行にまたがることができます。配列の最後の値の後に、終端コンマ(末尾コンマとも呼ばれます)を使用できます。任意の数の改行とコメントが、値、コンマ、および閉じかっこ précéder できます。配列値とコンマの間のインデントは空白として扱われ、無視されます。

integers2 = [
  1, 2, 3
]

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

テーブル

テーブル(ハッシュテーブルまたは辞書とも呼ばれます)は、キー/値ペアのコレクションです。それらは、単独で角かっこが付いたヘッダーによって定義されます。配列は常に値であるため、ヘッダーを配列と区別できます。

[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

[x] # defining a super-table afterward is ok

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

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

# DO NOT DO THIS

[fruit]
apple = "red"

[fruit]
orange = "orange"
# DO NOT DO THIS EITHER

[fruit]
apple = "red"

[fruit.apple]
texture = "smooth"

テーブルを順不同で定義することはお勧めしません。

# VALID BUT DISCOURAGED
[fruit.apple]
[animal]
[fruit.orange]
# RECOMMENDED
[fruit.apple]
[fruit.orange]
[animal]

ルートテーブルとも呼ばれるトップレベルテーブルは、ドキュメントの先頭から始まり、最初のテーブルヘッダー(またはEOF)の直前で終わります。他のテーブルとは異なり、名前がなく、再配置できません。

# Top-level table begins.
name = "Fido"
breed = "pug"

# Top-level table ends.
[owner]
name = "Regina Dogman"
member_since = 1999-08-04

ドット付きキーは、そのようなテーブルが以前に作成されていない場合、最後のキー部分の前に各キー部分のテーブルを作成して定義します。

fruit.apple.color = "red"
# Defines a table named fruit
# Defines a table named fruit.apple

fruit.apple.taste.sweet = true
# Defines a table named fruit.apple.taste
# fruit and fruit.apple were already created

テーブルは複数回定義できないため、[table]ヘッダーを使用してそのようなテーブルを再定義することはできません。同様に、ドット付きキーを使用して、[table]形式で既に定義されているテーブルを再定義することはできません。ただし、[table]

[fruit]
apple.color = "red"
apple.taste.sweet = true

# [fruit.apple]  # INVALID
# [fruit.apple.taste]  # INVALID

[fruit.apple.texture]  # you can add sub-tables
smooth = true

インラインテーブル

インラインテーブルは、テーブルを表現するためのよりコンパクトな構文を提供します。特に、冗長になりがちなグループ化されたデータに役立ちます。インラインテーブルは、中括弧:{} の中に完全に定義されます。中括弧内には、ゼロ個以上のカンマ区切りのキーと値のペアを記述できます。キーと値のペアは、標準テーブルのキーと値のペアと同じ形式を取ります。インラインテーブルを含む、すべての値の型が許可されます。

インラインテーブルは、1行で記述することを意図しています。インラインテーブルの最後のキーと値のペアの後には、終端カンマ(末尾カンマとも呼ばれます)は許可されません。中括弧の間には、値の中で有効な場合を除いて、改行は許可されません。たとえ有効な場合でも、インラインテーブルを複数行に分割することは強くお勧めしません。複数行に分割したい場合は、標準テーブルを使用するべきです。

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"

インラインテーブルは完全に自己完結型であり、すべてのキーとサブテーブルをその内部で定義します。キーとサブテーブルを中括弧の外に追加することはできません。

[product]
type = { name = "Nail" }
# type.edible = false  # INVALID

同様に、インラインテーブルを使用して、既に定義されているテーブルにキーまたはサブテーブルを追加することはできません。

[product]
type.name = "Nail"
# type = { edible = false }  # INVALID

テーブルの配列

まだ説明されていない最後の構文は、テーブルの配列を記述することを可能にします。これらは、二重角括弧で囲まれた名前を持つヘッダーを使用することで表現できます。そのヘッダーの最初のインスタンスは配列とその最初のテーブル要素を定義し、後続の各インスタンスはその配列に新しいテーブル要素を作成して定義します。テーブルは、見つかった順序で配列に挿入されます。

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

[[products]]  # empty table within the array

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

color = "gray"

JSON で表現すると、以下の構造になります。

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

テーブルの配列への参照は、配列の最後に定義されたテーブル要素を指します。これにより、最新のテーブル内にサブテーブル、さらにはテーブルのサブ配列を定義できます。

[[fruits]]
name = "apple"

[fruits.physical]  # subtable
color = "red"
shape = "round"

[[fruits.varieties]]  # nested array of tables
name = "red delicious"

[[fruits.varieties]]
name = "granny smith"


[[fruits]]
name = "banana"

[[fruits.varieties]]
name = "plantain"

上記のTOMLは、次のJSONにマッピングされます。

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

テーブルまたはテーブルの配列の親が配列要素である場合、子は定義される前にその要素が既に定義されている必要があります。その順序を逆にする試みは、解析時にエラーを生成する必要があります。

# INVALID TOML DOC
[fruit.physical]  # subtable, but to which parent element should it belong?
color = "red"
shape = "round"

[[fruit]]  # parser must throw an error upon discovering that "fruit" is
           # an array rather than a table
name = "apple"

静的に定義された配列に、たとえその配列が空であっても、追加しようとすると、解析時にエラーが発生する必要があります。

# INVALID TOML DOC
fruits = []

[[fruits]] # Not allowed

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

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

[[fruits.varieties]]
name = "red delicious"

# INVALID: This table conflicts with the previous array of tables
[fruits.varieties]
name = "granny smith"

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

# INVALID: This array of tables conflicts with the previous table
[[fruits.physical]]
color = "green"

必要に応じてインラインテーブルを使用することもできます。

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です。

ABNF 文法

TOML の構文の正式な説明は、別のABNF ファイルとして入手できます。