TOML v0.3.0
Tom's Obvious, Minimal Language.(汤姆的显而易见、极简语言)
作者:Tom Preston-Werner。
注意,此规范仍在不断变化。在标记为 1.0 之前,您应该假设它是不稳定的,并相应地采取行动。
目标
TOML 旨在成为一种极简的配置文件格式,由于其明显的语义,易于阅读。TOML 旨在明确地映射到哈希表。TOML 应该易于解析成各种语言中的数据结构。
规范
- TOML 区分大小写。
- 空白字符是指制表符 (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)
任何 Unicode 字符都可以使用\uXXXX
或\UXXXXXXXX
形式转义。请注意,转义代码必须是有效的 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
不允许前导零。不允许使用十六进制、八进制和二进制形式。诸如“infinity”和“not a number”之类的值无法表示为一系列数字,因此不允许使用。
预期为 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]
在它下面,直到下一个表或文件结尾,都是该表的键/值。键位于等号的左侧,值位于右侧。键从第一个不是空白字符或[
的字符开始,到等号之前的最后一个非空白字符结束。键不能包含#
字符。表内的键/值对没有保证按任何特定顺序排列。
[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 不算数。你知道为什么。
哦天哪,你说得对
是的。想帮忙吗?发送拉取请求。或者编写一个解析器。要勇敢。
实现
如果您有实现,请发送拉取请求以添加到此列表中。请在您的自述文件中注意您的解析器支持的提交 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#/.NET - https://github.com/azyobuzin/HyperTomlProcessor
- C (@ajwans) - https://github.com/ajwans/libtoml
- C (@mzgoddard) - https://github.com/mzgoddard/tomlc
- 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
- Go (@achun) - https://github.com/achun/tom-toml
- Go (@naoina) - https://github.com/naoina/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/ricardobeat/toml.js (npm install tomljs)
- node.js - https://github.com/BinaryMuse/toml-node
- node.js/浏览器 (@redhotvengeance) - https://github.com/redhotvengeance/topl (topl npm 包)
- node.js/浏览器 (@alexanderbeletsky) - https://github.com/alexanderbeletsky/toml-js (npm 浏览器 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 (@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
- Racket (@greghendershott) - https://github.com/greghendershott/toml
- 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)
- Rust (@mneumann) - https://github.com/mneumann/rust-toml
- Rust (@alexcrichton) - https://github.com/alexcrichton/toml-rs
- Scala - https://github.com/axelarge/tomelette
验证器
- Go (@BurntSushi) - https://github.com/BurntSushi/toml/tree/master/cmd/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
- Notepad++ (@fireforge) - https://github.com/fireforge/toml-notepadplusplus
编码器
- Go w/ Reflection (@BurntSushi) - https://github.com/BurntSushi/toml
- PHP (@ayushchd) - https://github.com/ayushchd/php-toml-encoder
转换器
- remarshal (@dbohdan) - https://github.com/dbohdan/remarshal