1. 程式人生 > >TOML: GitHub 這是要革 YAML 的命呀!

TOML: GitHub 這是要革 YAML 的命呀!

GitHub 目前的新專案已經轉用 CoffeeScript 了。CoffeeScript 比 JavaScript 要簡潔優雅得多。同樣地,GitHub 也覺得 YAML 不夠簡潔優雅,因此搗鼓出了一個TOML

TOML 的全稱是 Tom's Obvious, Minimal Language,因為它的作者是 GitHub 聯合創始人 Tom Preston-Werner 。

TOML 的目標

TOML 的目標是成為一個極簡的配置檔案格式。TOML 被設計成可以無歧義地被對映為雜湊表,從而被多種語言解析。

例子

title ="TOML 例子"[owner]
name 
="Tom Preston-Werner
"
organization 
="GitHub"
bio 
="GitHub Cofounder & CEO\nLikes tater tots and beer."
dob 
=1979-05-27T07:32:00Z # 日期時間是一等公民。為什麼不呢?

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

[servers]

  # 你可以依照你的意願縮排。使用空格或Tab。TOML不會在意。
  
[servers.alpha]
  ip 
="10.0.0.1"
  dc 
="eqdc10"[servers.beta
]
  ip 
="10.0.0.2"
  dc 
="eqdc10"[clients]
data 
=[ ["gamma", "delta"],[1, 2] ]

# 在數組裡換行沒有關係。
hosts 
=[
"alpha","omega"
]
TOML 是大小寫敏感的。

註釋

使用 # 表示註釋:

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

字串

字串和 JSON 的定義一致,只有一點除外: TOML 要求使用 UTF-8 編碼。

註釋以引號包裹,裡面的字元必須是 UTF-8 格式。引號、反斜槓和控制字元(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)

使用保留的特殊字元,TOML 會丟擲錯誤。例如,在 Windows 平臺上,應該使用兩個反斜槓來表示路徑:

wrong ="C:\Users\nodejs\templates" # 注意:這不會生成合法的路徑。
right 
="C:\\Users\\nodejs\\templates"

二進位制資料建議使用 Base64 或其他合適的編碼。具體的處理取決於特定的應用。

整數

整數就是一些沒有小數點的數字。想用負數?按直覺來就行。整數的尺寸最小為64位。

浮點數

浮點數帶小數點。小數點兩邊都有數字。64位精度。

3.1415
-0.01 

布林值

布林值永遠是小寫。

true
false 

日期時間

使用 ISO 8601 完整格式。

1979-05-27T07:32:00Z 

 陣列

陣列使用方括號包裹。空格會被忽略。元素使用逗號分隔。注意,不允許混用資料型別。

[ 1, 2, 3 ]
[ "red", "yellow", "green" ]
[ [ 1, 2 ], [3, 4, 5] ]
[ [ 1, 2 ], ["a", "b", "c"] ] # 這是可以的。 
[ 1, 2.0 ] # 注意:這是不行的。 

陣列可以多行。也就是說,除了空格之外,方括號間的換行也會被忽略。在關閉方括號前的最終項後的逗號是允許的。

表格

表格(也叫雜湊表或字典)是鍵值對的集合。它們在方括號內,自成一行。注意和陣列相區分,陣列只有值。

[table] 

在此之下,直到下一個 table 或 EOF 之前,是這個表格的鍵值對。鍵在左,值在右,等號在中間。鍵以非空字元開始,以等號前的非空字元為結尾。鍵值對是無序的。

[table] key = "value" 

你可以隨意縮排,使用 Tab 或空格。為什麼要縮排呢?因為你可以巢狀表格。

巢狀表格的表格名稱中使用.。你可以任意命名你的表格,只是不要用點,點是保留的。

[dog.tater] type = "pug" 

以上等價於如下的 JSON 結構:

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

如果你不想的話,你不用宣告所有的父表。TOML 知道該如何處理。

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

表格陣列

最後要介紹的型別是表格陣列。表格陣列可以通過包裹在雙方括號內的表格名來表達。使用相同的雙方括號名稱的表格是同一個陣列的元素。表格按照書寫的順序插入。雙方括號表格如果沒有鍵值對,會被當成空表。

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

等價於如下的 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"

來真的?

是的。

但是為什麼?

因為我們需要一個像樣的人類可讀的格式,同時能無歧義地對映到雜湊表。然後 YAML 的規範有 80 頁那麼長,真是髮指!不,不考慮 JSON 。你知道為什麼。

天哪,你是對的!

哈哈!想幫忙麼?發合併請求過來。或者編寫一個解析器。勇敢一點。

實現

如果你有一個實現,請發一個合併請求,把你的實現加入到這個列表中。請在你的解析器的 README 中標記你的解析器支援的 提交SHA1 或 版本號。

校驗

TOML 測試套件 (語言無關)

編輯器支援

編碼器