|
| 1 | +TOML v0.1.0 |
| 2 | +=========== |
| 3 | + |
| 4 | +Tom's Obvious, Minimal Language. |
| 5 | + |
| 6 | +By Tom Preston-Werner. |
| 7 | + |
| 8 | +Be warned, this spec is still changing a lot. Until it's marked as 1.0, you |
| 9 | +should assume that it is unstable and act accordingly. |
| 10 | + |
| 11 | +Objectives |
| 12 | +---------- |
| 13 | + |
| 14 | +TOML aims to be a minimal configuration file format that's easy to read due to |
| 15 | +obvious semantics. TOML is designed to map unambiguously to a hash table. TOML |
| 16 | +should be easy to parse into data structures in a wide variety of languages. |
| 17 | + |
| 18 | +Example |
| 19 | +------- |
| 20 | + |
| 21 | +```toml |
| 22 | +# This is a TOML document. Boom. |
| 23 | + |
| 24 | +title = "TOML Example" |
| 25 | + |
| 26 | +[owner] |
| 27 | +name = "Tom Preston-Werner" |
| 28 | +organization = "GitHub" |
| 29 | +bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." |
| 30 | +dob = 1979-05-27T07:32:00Z # First class dates? Why not? |
| 31 | + |
| 32 | +[database] |
| 33 | +server = "192.168.1.1" |
| 34 | +ports = [ 8001, 8001, 8002 ] |
| 35 | +connection_max = 5000 |
| 36 | +enabled = true |
| 37 | + |
| 38 | +[servers] |
| 39 | + |
| 40 | + # You can indent as you please. Tabs or spaces. TOML don't care. |
| 41 | + [servers.alpha] |
| 42 | + ip = "10.0.0.1" |
| 43 | + dc = "eqdc10" |
| 44 | + |
| 45 | + [servers.beta] |
| 46 | + ip = "10.0.0.2" |
| 47 | + dc = "eqdc10" |
| 48 | + |
| 49 | +[clients] |
| 50 | +data = [ ["gamma", "delta"], [1, 2] ] |
| 51 | + |
| 52 | +# Line breaks are OK when inside arrays |
| 53 | +hosts = [ |
| 54 | + "alpha", |
| 55 | + "omega" |
| 56 | +] |
| 57 | +``` |
| 58 | + |
| 59 | +Spec |
| 60 | +---- |
| 61 | + |
| 62 | +* TOML is case sensitive. |
| 63 | +* Whitespace means tab (0x09) or space (0x20). |
| 64 | + |
| 65 | +Comment |
| 66 | +------- |
| 67 | + |
| 68 | +Speak your mind with the hash symbol. They go from the symbol to the end of the |
| 69 | +line. |
| 70 | + |
| 71 | +```toml |
| 72 | +# I am a comment. Hear me roar. Roar. |
| 73 | +key = "value" # Yeah, you can do this. |
| 74 | +``` |
| 75 | + |
| 76 | +String |
| 77 | +------ |
| 78 | + |
| 79 | +ProTip™: You may notice that this specification is the same as JSON's string |
| 80 | +definition, except that TOML requires UTF-8 encoding. This is on purpose. |
| 81 | + |
| 82 | +Strings are single-line values surrounded by quotation marks. Strings must |
| 83 | +contain only valid UTF-8 characters. Any Unicode character maybe be used except |
| 84 | +those that must be escaped: quotation mark, backslash, and the control |
| 85 | +characters (U+0000 to U+001F). |
| 86 | + |
| 87 | +```toml |
| 88 | +"I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF." |
| 89 | +``` |
| 90 | + |
| 91 | +For convenience, some popular characters have a compact escape sequence. |
| 92 | + |
| 93 | +``` |
| 94 | +\b - backspace (U+0008) |
| 95 | +\t - tab (U+0009) |
| 96 | +\n - linefeed (U+000A) |
| 97 | +\f - form feed (U+000C) |
| 98 | +\r - carriage return (U+000D) |
| 99 | +\" - quote (U+0022) |
| 100 | +\/ - slash (U+002F) |
| 101 | +\\ - backslash (U+005C) |
| 102 | +\uXXXX - unicode (U+XXXX) |
| 103 | +``` |
| 104 | + |
| 105 | +Any Unicode character may be escaped with the `\uXXXX` form. |
| 106 | + |
| 107 | +Other special characters are reserved and, if used, TOML should produce an |
| 108 | +error. This means paths on Windows will always have to use double backslashes. |
| 109 | + |
| 110 | +```toml |
| 111 | +wrong = "C:\Users\nodejs\templates" # note: doesn't produce a valid path |
| 112 | +right = "C:\\Users\\nodejs\\templates" |
| 113 | +``` |
| 114 | + |
| 115 | +For binary data it is recommended that you use Base 64 or another suitable |
| 116 | +encoding. The handling of that encoding will be application specific. |
| 117 | + |
| 118 | +Integer |
| 119 | +------- |
| 120 | + |
| 121 | +Integers are bare numbers, all alone. Feeling negative? Do what's natural. |
| 122 | +64-bit minimum size expected. |
| 123 | + |
| 124 | +```toml |
| 125 | +42 |
| 126 | +-17 |
| 127 | +``` |
| 128 | + |
| 129 | +Float |
| 130 | +----- |
| 131 | + |
| 132 | +Floats are numbers with a single dot within. There must be at least one number |
| 133 | +on each side of the decimal point. 64-bit (double) precision expected. |
| 134 | + |
| 135 | +```toml |
| 136 | +3.1415 |
| 137 | +-0.01 |
| 138 | +``` |
| 139 | + |
| 140 | +Boolean |
| 141 | +------- |
| 142 | + |
| 143 | +Booleans are just the tokens you're used to. Always lowercase. |
| 144 | + |
| 145 | +```toml |
| 146 | +true |
| 147 | +false |
| 148 | +``` |
| 149 | + |
| 150 | +Datetime |
| 151 | +-------- |
| 152 | + |
| 153 | +Datetimes are ISO8601 dates, but only the full zulu form is allowed. |
| 154 | + |
| 155 | +```toml |
| 156 | +1979-05-27T07:32:00Z |
| 157 | +``` |
| 158 | + |
| 159 | +Array |
| 160 | +----- |
| 161 | + |
| 162 | +Arrays are square brackets with other primitives inside. Whitespace is ignored. |
| 163 | +Elements are separated by commas. No, you can't mix data types, that's stupid. |
| 164 | + |
| 165 | +```toml |
| 166 | +[ 1, 2, 3 ] |
| 167 | +[ "red", "yellow", "green" ] |
| 168 | +[ [ 1, 2 ], [3, 4, 5] ] |
| 169 | +[ [ 1, 2 ], ["a", "b", "c"] ] # this is ok |
| 170 | +[ 1, 2.0 ] # note: this is NOT ok |
| 171 | +``` |
| 172 | + |
| 173 | +Arrays can also be multiline. So in addition to ignoring whitespace, arrays also |
| 174 | +ignore newlines between the brackets. Terminating commas are ok before the |
| 175 | +closing bracket. |
| 176 | + |
| 177 | +```toml |
| 178 | +key = [ |
| 179 | + 1, 2, 3 |
| 180 | +] |
| 181 | + |
| 182 | +key = [ |
| 183 | + 1, |
| 184 | + 2, # this is ok |
| 185 | +] |
| 186 | +``` |
| 187 | + |
| 188 | +Hash |
| 189 | +---- |
| 190 | + |
| 191 | +There are two ways to make keys. I call them "key groups" and "keys". Both are |
| 192 | +just regular keys, but key groups only ever have a single hash as their value. |
| 193 | + |
| 194 | +Key groups appear in square brackets on a line by themselves. You can tell them |
| 195 | +apart from arrays because arrays are only ever values. |
| 196 | + |
| 197 | +```toml |
| 198 | +[keygroup] |
| 199 | +``` |
| 200 | + |
| 201 | +Under that, and until the next key or EOF are the key/values of that key group. |
| 202 | +Keys are on the left of the equals sign and values are on the right. Keys start |
| 203 | +with the first non-whitespace character and end with the last non-whitespace |
| 204 | +character before the equals sign. Key/value pairs within key groups are |
| 205 | +unordered. |
| 206 | + |
| 207 | +```toml |
| 208 | +[keygroup] |
| 209 | +key = "value" |
| 210 | +``` |
| 211 | + |
| 212 | +You can indent keys and their values as much as you like. Tabs or spaces. Knock |
| 213 | +yourself out. Why, you ask? Because you can have nested hashes. Snap. |
| 214 | + |
| 215 | +Nested hashes are denoted by key groups with dots in them. Name your key groups |
| 216 | +whatever crap you please, just don't use a dot. Dot is reserved. OBEY. |
| 217 | + |
| 218 | +```toml |
| 219 | +[key.tater] |
| 220 | +type = "pug" |
| 221 | +``` |
| 222 | + |
| 223 | +In JSON land, that would give you the following structure. |
| 224 | + |
| 225 | +```json |
| 226 | +{ "key": { "tater": { "type": "pug" } } } |
| 227 | +``` |
| 228 | + |
| 229 | +You don't need to specify all the superkeys if you don't want to. TOML knows how |
| 230 | +to do it for you. |
| 231 | + |
| 232 | +```toml |
| 233 | +# [x] you |
| 234 | +# [x.y] don't |
| 235 | +# [x.y.z] need these |
| 236 | +[x.y.z.w] # for this to work |
| 237 | +``` |
| 238 | + |
| 239 | +When converted to a hash table, an empty key group should result in the key's |
| 240 | +value being an empty hash table. |
| 241 | + |
| 242 | +Be careful not to overwrite previous keys. That's dumb. And should produce an |
| 243 | +error. |
| 244 | + |
| 245 | +```toml |
| 246 | +# DO NOT WANT |
| 247 | +[fruit] |
| 248 | +type = "apple" |
| 249 | + |
| 250 | +[fruit.type] |
| 251 | +apple = "yes" |
| 252 | +``` |
| 253 | + |
| 254 | +Seriously? |
| 255 | +---------- |
| 256 | + |
| 257 | +Yep. |
| 258 | + |
| 259 | +But why? |
| 260 | +-------- |
| 261 | + |
| 262 | +Because we need a decent human readable format that maps to a hash and the YAML |
| 263 | +spec is like 80 pages long and gives me rage. No, JSON doesn't count. You know |
| 264 | +why. |
| 265 | + |
| 266 | +Oh god, you're right |
| 267 | +-------------------- |
| 268 | + |
| 269 | +Yuuuup. Wanna help? Send a pull request. Or write a parser. BE BRAVE. |
| 270 | + |
| 271 | +Implementations |
| 272 | +--------------- |
| 273 | + |
| 274 | +If you have an implementation, send a pull request adding to this list. Please |
| 275 | +note the commit SHA1 or version tag that your parser supports in your Readme. |
| 276 | + |
| 277 | +- C#/.NET - https://github.com/LBreedlove/Toml.net |
| 278 | +- C#/.NET - https://github.com/rossipedia/toml-net |
| 279 | +- C#/.NET - https://github.com/RichardVasquez/TomlDotNet |
| 280 | +- C (@ajwans) - https://github.com/ajwans/libtoml |
| 281 | +- C++ (@evilncrazy) - https://github.com/evilncrazy/ctoml |
| 282 | +- Clojure (@lantiga) - https://github.com/lantiga/clj-toml |
| 283 | +- Clojure (@manicolosi) - https://github.com/manicolosi/clojoml |
| 284 | +- CoffeeScript (@biilmann) - https://github.com/biilmann/coffee-toml |
| 285 | +- Erlang - https://github.com/kalta/etoml.git |
| 286 | +- Erlang - https://github.com/kaos/tomle |
| 287 | +- Go (@thompelletier) - https://github.com/pelletier/go-toml |
| 288 | +- Go (@laurent22) - https://github.com/laurent22/toml-go |
| 289 | +- Go w/ Reflection (@BurntSushi) - https://github.com/BurntSushi/toml |
| 290 | +- Haskell (@seliopou) - https://github.com/seliopou/toml |
| 291 | +- Java (@agrison) - https://github.com/agrison/jtoml |
| 292 | +- Java (@johnlcox) - https://github.com/johnlcox/toml4j |
| 293 | +- Java (@mwanji) - https://github.com/mwanji/toml4j |
| 294 | +- Java - https://github.com/asafh/jtoml |
| 295 | +- Java w/ ANTLR (@MatthiasSchuetz) - https://github.com/mschuetz/toml |
| 296 | +- Julia (@pygy) - https://github.com/pygy/TOML.jl |
| 297 | +- Literate CoffeeScript (@JonathanAbrams) - https://github.com/JonAbrams/tomljs |
| 298 | +- node.js - https://github.com/aaronblohowiak/toml |
| 299 | +- node.js/browser - https://github.com/ricardobeat/toml.js (npm install tomljs) |
| 300 | +- node.js - https://github.com/BinaryMuse/toml-node |
| 301 | +- node.js (@redhotvengeance) - https://github.com/redhotvengeance/topl (topl npm package) |
| 302 | +- node.js/browser (@alexanderbeletsky) - https://github.com/alexanderbeletsky/toml-js (npm browser amd) |
| 303 | +- Objective C (@mneorr) - https://github.com/mneorr/toml-objc.git |
| 304 | +- Objective-C (@SteveStreza) - https://github.com/amazingsyco/TOML |
| 305 | +- Ocaml (@mackwic) https://github.com/mackwic/to.ml |
| 306 | +- Perl (@alexkalderimis) - https://github.com/alexkalderimis/config-toml.pl |
| 307 | +- Perl - https://github.com/dlc/toml |
| 308 | +- PHP (@leonelquinteros) - https://github.com/leonelquinteros/php-toml.git |
| 309 | +- PHP (@jimbomoss) - https://github.com/jamesmoss/toml |
| 310 | +- PHP (@coop182) - https://github.com/coop182/toml-php |
| 311 | +- PHP (@checkdomain) - https://github.com/checkdomain/toml |
| 312 | +- PHP (@zidizei) - https://github.com/zidizei/toml-php |
| 313 | +- Python (@socketubs) - https://github.com/socketubs/pytoml |
| 314 | +- Python (@f03lipe) - https://github.com/f03lipe/toml-python |
| 315 | +- Python (@uiri) - https://github.com/uiri/toml |
| 316 | +- Python - https://github.com/bryant/pytoml |
| 317 | +- Python (@elssar) - https://github.com/elssar/tomlgun |
| 318 | +- Python (@marksteve) - https://github.com/marksteve/toml-ply |
| 319 | +- Ruby (@jm) - https://github.com/jm/toml (toml gem) |
| 320 | +- Ruby (@eMancu) - https://github.com/eMancu/toml-rb (toml-rb gem) |
| 321 | +- Ruby (@charliesome) - https://github.com/charliesome/toml2 (toml2 gem) |
| 322 | +- Ruby (@sandeepravi) - https://github.com/sandeepravi/tomlp (tomlp gem) |
| 323 | +- Scala - https://github.com/axelarge/tomelette |
| 324 | + |
| 325 | +Validators |
| 326 | +---------- |
| 327 | + |
| 328 | +- Go (@BurntSushi) - https://github.com/BurntSushi/toml/tree/master/tomlv |
| 329 | + |
| 330 | +Language agnostic test suite for TOML parsers |
| 331 | +--------------------------------------------- |
| 332 | + |
| 333 | +- toml-test (@BurntSushi) - https://github.com/BurntSushi/toml-test |
| 334 | + |
| 335 | +Editor support |
| 336 | +-------------- |
| 337 | + |
| 338 | +- Emacs (@dryman) - https://github.com/dryman/toml-mode.el |
| 339 | +- Sublime Text 2 (@lmno) - https://github.com/lmno/TOML |
| 340 | +- TextMate (@infininight) - https://github.com/textmate/toml.tmbundle |
| 341 | +- Vim (@cespare) - https://github.com/cespare/vim-toml |
| 342 | + |
| 343 | +Encoder |
| 344 | +-------------- |
| 345 | +- PHP (@ayushchd) - https://github.com/ayushchd/php-toml-encoder |
0 commit comments