TOML: GitHub 這是要革 YAML 的命呀!
轉載自:https://segmentfault.com/a/1190000000477752GitHub 目前的新項目已經轉用 CoffeeScript 了。CoffeeScript 比 JavaScript 要簡潔優雅得多。同樣地,GitHub 也覺得 YAML 不夠簡潔優雅,因此搗鼓出了一個TOML。
TOML 的全稱是 Tom's Obvious, Minimal Language,因為它的作者是 GitHub 聯合創始人 Tom Preston-Werner 。
TOML 的目標
TOML 的目標是成為一個極簡的配置文件格式。TOML 被設計成可以無歧義地被映射為哈希表,從而被多種語言解析。
例子
title = "TOML 例子"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"
]
注釋
使用 #
表示注釋:
# 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 或 版本號。
- C#/.NET - https://github.com/LBreedlove/Toml.net
- C#/.NET - https://github.com/rossipedia/toml-net
- C#/.NET - https://github.com/RichardVasquez/TomlDotNet
- C (@ajwans) - https://github.com/ajwans/libtoml
- C++ (@evilncrazy) - https://github.com/evilncrazy/ctoml
- C++ (@skystrife) - https://github.com/skystrife/cpptoml
- Clojure (@lantiga) - https://github.com/lantiga/clj-toml
- Clojure (@manicolosi) - https://github.com/manicolosi/clojoml
- CoffeeScript (@biilmann) - https://github.com/biilmann/coffee-toml
- Common Lisp (@pnathan) - https://github.com/pnathan/pp-toml
- Erlang - https://github.com/kalta/etoml.git
- Erlang - https://github.com/kaos/tomle
- Emacs Lisp (@gongoZ) - https://github.com/gongo/emacs-toml
- Go (@thompelletier) - https://github.com/pelletier/go-toml
- Go (@laurent22) - https://github.com/laurent22/toml-go
- Go w/ Reflection (@BurntSushi) - https://github.com/BurntSushi/toml
- Haskell (@seliopou) - https://github.com/seliopou/toml
- Haxe (@raincole) - https://github.com/raincole/haxetoml
- Java (@agrison) - https://github.com/agrison/jtoml
- Java (@johnlcox) - https://github.com/johnlcox/toml4j
- Java (@mwanji) - https://github.com/mwanji/toml4j
- Java - https://github.com/asafh/jtoml
- Java w/ ANTLR (@MatthiasSchuetz) - https://github.com/mschuetz/toml
- Julia (@pygy) - https://github.com/pygy/TOML.jl
- Literate CoffeeScript (@JonathanAbrams) - https://github.com/JonAbrams/tomljs
- node.js - https://github.com/aaronblohowiak/toml
- node.js/browser - https://github.com/ricardobeat/toml.js (npm install tomljs)
- node.js - https://github.com/BinaryMuse/toml-node
- node.js (@redhotvengeance) - https://github.com/redhotvengeance/topl (topl npm package)
- node.js/browser (@alexanderbeletsky) - https://github.com/alexanderbeletsky/toml-js (npm browser amd)
- Objective C (@mneorr) - https://github.com/mneorr/toml-objc.git
- Objective-C (@SteveStreza) - https://github.com/amazingsyco/TOML
- Ocaml (@mackwic) https://github.com/mackwic/to.ml
- Perl (@alexkalderimis) - https://github.com/alexkalderimis/config-toml.pl
- Perl - https://github.com/dlc/toml
- PHP (@leonelquinteros) - https://github.com/leonelquinteros/php-toml.git
- PHP (@jimbomoss) - https://github.com/jamesmoss/toml
- PHP (@coop182) - https://github.com/coop182/toml-php
- PHP (@checkdomain) - https://github.com/checkdomain/toml
- PHP (@zidizei) - https://github.com/zidizei/toml-php
- PHP (@yosymfony) - https://github.com/yosymfony/toml
- Python (@socketubs) - https://github.com/socketubs/pytoml
- Python (@f03lipe) - https://github.com/f03lipe/toml-python
- Python (@uiri) - https://github.com/uiri/toml
- Python - https://github.com/bryant/pytoml
- Python (@elssar) ) https://github.com/elssar/tomlgun
- Python (@marksteve) - https://github.com/marksteve/toml-ply
- Python (@hit9) - https://github.com/hit9/toml.py
- Ruby (@jm) - https://github.com/jm/toml (toml gem)
- Ruby (@eMancu) - https://github.com/eMancu/toml-rb (toml-rb gem)
- Ruby (@charliesome) - https://github.com/charliesome/toml2 (toml2 gem)
- Ruby (@sandeepravi) - https://github.com/sandeepravi/tomlp (tomlp gem)
- Scala - https://github.com/axelarge/tomelette
校驗
@BurntSushi) - https://github.com/BurntSushi/toml/tree/master/tomlv
TOML 測試套件 (語言無關)
- toml-test (@BurntSushi) - https://github.com/BurntSushi/toml-test
編輯器支持
- Emacs (@dryman) - https://github.com/dryman/toml-mode.el
- Sublime Text 2 & 3 (@lmno) - https://github.com/lmno/TOML
- TextMate (@infininight) - https://github.com/textmate/toml.tmbundle
- Vim (@cespare) - https://github.com/cespare/vim-toml
編碼器
- PHP (@ayushchd) - https://github.com/ayushchd/php-toml-encoder
原文 TOML README
翻譯 SegmentFault