v1.0.0
發布於 11/10/2014 – 文字版本

TOML v0.3.0

Tom 的顯而易見、極簡語言。

作者:Tom Preston-Werner。

請注意,此規格仍在大幅變動中。在標示為 1.0 之前,您應假設它不穩定並採取相應措施。

目標

TOML 的目標是成為一種極簡的設定檔格式,由於語意明顯,因此易於閱讀。TOML 設計為明確對應至雜湊表。TOML 應易於解析為各種語言中的資料結構。

規格

  • TOML 區分大小寫。
  • 空白表示 tab (0x09) 或空白 (0x20)。

註解

使用井號符號表達您的想法。它們從符號延伸到該行的結尾。

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

字串

有四種表達字串的方式:基本、多行基本、字面值和多行字面值。所有字串都必須只包含有效的 UTF-8 字元。

基本字串以引號包圍。可以使用任何 Unicode 字元,但必須跳脫下列字元:引號、反斜線和控制字元(U+0000 至 U+001F)。

"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)
\/         - slash           (U+002F)
\\         - backslash       (U+005C)
\uXXXX     - unicode         (U+XXXX)
\UXXXXXXXX - unicode         (U+XXXXXXXX)

可以使用 \uXXXX\UXXXXXXXX 形式跳脫任何 Unicode 字元。請注意,跳脫碼必須是有效的 Unicode 碼點。

其他特殊字元是保留字元,如果使用,TOML 應產生錯誤。

專業提示™:您可能會注意到,上述字串規格與 JSON 的字串定義相同,但 TOML 需要 UTF-8 編碼。這是故意的。

有時您需要表達文字段落(例如翻譯檔),或想要將很長的字串分成多行。TOML 讓這變得容易。多行基本字串兩側各有三個引號,並允許換行。如果開頭分隔符號後的字元為換行符號(0x0A),則會將其修剪。所有其他空白保持不變。

# The following strings are byte-for-byte equivalent:
key1 = "One\nTwo"
key2 = """One\nTwo"""
key3 = """
One
Two"""

若要撰寫長字串而不引入多餘的空白,請以 \ 結束一行。\ 將會與所有空白(包括換行符號)一起修剪,直到下一個非空白字元或結束分隔符號。如果開頭分隔符號後的兩個字元為反斜線和換行符號(0x5C0A),則它們將會與所有空白(包括換行符號)一起修剪,直到下一個非空白字元或結束分隔符號。所有對基本字串有效的跳脫序列對多行基本字串也都有效。

# 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.\
       """

可以使用任何 Unicode 字元,但必須跳脫下列字元:反斜線和控制字元(U+0000 至 U+001F)。引號不需要跳脫,除非它們的存在會產生過早的結束分隔符號。

如果您經常指定 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 支援多行版本的字面字串來解決此問題。多行字面字串兩側各有三個單引號,並允許換行。與字面字串一樣,完全沒有跳脫。如果開頭分隔符號後的字元為換行符號(0x0A),則會將其修剪。分隔符號之間的所有其他內容都會照樣解釋,而不會修改。

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

不允許前導零。不允許十六進位、八進位和二進位形式。不允許無法表示為一系列數字的值,例如「無限大」和「非數字」。

預期 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

小數部分是小數點後接一個或多個數字。

指數部分為 E(大寫或小寫),後接整數部分(可能加上正號或負號前綴)。

預期為 64 位元(雙倍)精度。

布林值

布林值就是您習慣的符號。總是小寫。

true
false

日期時間

日期時間為 RFC 3339 日期。

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

陣列

陣列為方括號,內含其他基本類型。空白會被忽略。元素以逗號分隔。資料類型不可混合。

[ 1, 2, 3 ]
[ "red", "yellow", "green" ]
[ [ 1, 2 ], [3, 4, 5] ]
[ [ 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
]

表格

表格(也稱為雜湊表或字典)是鍵/值對的集合。它們出現在單獨一行的方括號中。您可以將它們與陣列區分開,因為陣列永遠只會是值。

[table]

在表格下方,直到下一個表格或 EOF,都是該表格的鍵/值。鍵位於等號符號的左側,值位於右側。鍵從第一個非空白或 [ 字元開始,並以等號符號之前最後一個非空白字元結束。鍵不能包含 # 字元。表格中的鍵/值對不保證以任何特定順序排列。

[table]
key = "value"

您可以盡量縮排鍵及其值。標籤或空白。盡情發揮。您可能會問為什麼?因為您可以擁有巢狀表格。快照。

巢狀表格由名稱中帶有句點的表格名稱表示。您可以隨意命名您的表格,但不要使用 #.[]

[dog.tater]
type = "pug"

在 JSON 領域中,這將為您提供以下結構

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

如果您不願意,您不需要指定所有超級表格。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

表格陣列

尚未表達的最後一個類型是表格陣列。這些可以用雙括號中的表格名稱表示。具有相同雙括號名稱的每個表格將成為陣列中的元素。表格會按照遇到的順序插入。沒有任何鍵/值對的雙括號表格將被視為空表格。

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

認真嗎?

對。

但為什麼?

因為我們需要一個可讀性佳的人類可讀格式,可以明確地對應到雜湊表格,而 YAML 規格長達 80 頁,而且讓我抓狂。不,JSON 不算。你知道為什麼。

天啊,你說得對

Yuuuup。想幫忙嗎?傳送一個拉取請求。或撰寫一個解析器。勇敢一點。

實作

如果您有實作,請傳送一個拉取請求,將其新增到這個清單。請在您的 Readme 中註明您的解析器支援的提交 SHA1 或版本標籤。

驗證器

TOML 解碼器和編碼器的與語言無關測試套件

編輯器支援

編碼器

轉換器