Introduction

Toml is a small, easy-to-read language created by the former CEO of GitHub, Tom. Tom's Obvious, Minimal Language.

TOML is focused on minimizing and making configuration files easy to read.

  1. WIKI Introduction: https://github.com/toml-lang/toml/wiki
  2. Official Address: https://github.com/toml-lang/toml
  3. Chinese Version: https://github.com/LongTengDao/TOML/blob/%E9%BE%99%E8%85%BE%E9%81%93-%E8%AF%91/toml-v1.0.0.md

Comparison with Other Formats

TOML shares the same characteristics as other file formats like YAML and JSON used for application configuration and data serialization. Both TOML and JSON are simple and use ubiquitous data types, making them easy to parse by code or machines. TOML and YAML both emphasize human readability, such as comments, which make understanding the purpose of a given line easier. The distinct feature of TOML is that it supports comments (unlike JSON) while maintaining simplicity (unlike YAML).

Since TOML is explicitly designed as a configuration file format, parsing it is easy, but it is not intended to serialize arbitrary data structures. The top level of a TOML file is a hash table which can easily nest data in keys, but it doesn’t allow top-level arrays or floating point numbers, so it cannot directly serialize some data. There is no standard to identify the start or end of a TOML file, which complicates sending files over streams. These details must be negotiated at the application level.

INI files are often compared with TOML because of their syntactical similarity and common use as configuration files. However, INI files do not have a standardized format and do not handle more than one or two levels of nesting gracefully.

Basic Syntax

  1. title = "TOML Example"
  2. [owner]
  3. name = "Tom Preston-Werner"
  4. organization = "GitHub"
  5. bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
  6. dob = 1979-05-27T07:32:00Z # Date and time are first-class citizens. Why not?
  7. [database]
  8. server = "192.168.1.1"
  9. ports = [ 8001, 8001, 8002 ]
  10. connection_max = 5000
  11. enabled = true
  12. [servers]
  13. # You can indent as you please. Tabs or spaces. TOML doesn't care.
  14. [servers.alpha]
  15. ip = "10.0.0.1"
  16. dc = "eqdc10"
  17. [servers.beta]
  18. ip = "10.0.0.2"
  19. dc = "eqdc10"
  20. [clients]
  21. data = [ ["gamma", "delta"], [1, 2] ]
  22. # Newlines in arrays are no problem.
  23. hosts = [
  24. "alpha",
  25. "omega"
  26. ]

Features:

  • Case sensitive, must be UTF-8 encoded
  • Comments: #
  • Whitespace: tab(0x09) or space(0x20)
  • Newline: LF(0x0A) or CRLF(0x0D 0x0A)
  • Key-value pairs: single line, keys without a value are not allowed, only one key-value pair per line

TOML‘s primary structure is key-value pairs, similar to JSON. Values must be of the following types: String, Integer, Float, Boolean, Datetime, Array, Table

Comments

Comments are represented with #:

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

Strings

There are four ways of representing strings in TOML: basic, multi-line basic, literal, and multi-line literal.

1. Basic String

Enclosed in double quotes, all Unicode characters can appear, except double quotes, backslashes, and control characters (U+0000 to U+001F) which need to be escaped.

2. Multi-line Basic String

Enclosed in three double quotes, newlines within the string will be preserved, except for the newline at the start of the delimiter:

  1. str1 = """
  2. Roses are red
  3. Violets are blue"""

3. Literal String

Enclosed in single quotes, escapes are not allowed within, making it easy to represent content that needs to be escaped in basic strings:

  1. winpath = 'C:\Users\nodejs\templates'

4. Multi-line Literal String

Similar to a multi-line basic string:

  1. str1 = '''
  2. Roses are red
  3. Violets are blue'''

Numbers and BOOL Values

  1. int1 = +99
  2. flt3 = -0.01
  3. bool1 = true

Date and Time

  1. date = 1979-05-27T07:32:00Z

Arrays

Arrays are enclosed in square brackets. Spaces are ignored. Elements are separated by commas.

Note that mixing data types within the same array is not allowed.

  1. array1 = [ 1, 2, 3 ]
  2. array2 = [ "red", "yellow", "green" ]
  3. array3 = [ [ 1, 2 ], [3, 4, 5] ]
  4. array4 = [ [ 1, 2 ], ["a", "b", "c"] ] # This is allowed.
  5. array5 = [ 1, 2.0 ] # Note: This is not allowed.

Tables

Tables (also called hash tables or dictionaries) are collections of key-value pairs. They are their own line enclosed in square brackets. Note the distinction from arrays, which contain only values.

  1. [table]

Below this, until the next table or EOF, are the key-value pairs of this table. Keys on the left, values on the right, with an equal sign in between. Keys start with a non-space character and end with the last non-space character before the equal sign. Key-value pairs are unordered.

  1. [table]
  2. key = "value"

You can indent however you want, using Tabs or spaces. Why indent? Because you can nest tables.

Nested tables use the . symbol in the table name. You can name your tables as you like, just don’t use a dot, as it’s reserved.

  1. [dog.tater]
  2. type = "pug"

This is equivalent to the following JSON structure:

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

You don’t need to declare all parent tables if you don’t want to. TOML knows how to handle it.

  1. # [x] You
  2. # [x.y] don't need
  3. # [x.y.z] these
  4. [x.y.z.w] # You can write it directly

Empty tables are allowed, with no key-value pairs.

As long as a parent table hasn’t been defined directly and no specific key has been defined, you can continue writing:

  1. [a.b]
  2. c = 1
  3. [a]
  4. d = 2

However, you cannot redefine keys and tables multiple times. Doing so is illegal.

  1. # Don't do this!
  2. [a]
  3. b = 1
  4. [a]
  5. c = 2
  6. # Don't do this either
  7. [a]
  8. b = 1
  9. [a.b]
  10. c = 2

Table Arrays

The last type to introduce is table arrays. Table arrays are expressed by enclosing the table name within double square brackets. Tables with the same double bracket names are elements of the same array. Tables are inserted in the order they are written. Double bracket tables without key-value pairs are considered empty tables.

  1. [[products]]
  2. name = "Hammer"
  3. sku = 738594937
  4. [[products]]
  5. [[products]]
  6. name = "Nail"
  7. sku = 284758393
  8. color = "gray"

This is equivalent to the following JSON structure:

  1. {
  2. "products": [
  3. { "name": "Hammer", "sku": 738594937 },
  4. { },
  5. { "name": "Nail", "sku": 284758393, "color": "gray" }
  6. ]
  7. }

Table arrays can also be nested. Just use the same double bracket syntax on the child table. Each double-bracketed child table belongs to the most recently defined upper-level table element.

  1. [[fruit]]
  2. name = "apple"
  3. [fruit.physical]
  4. color = "red"
  5. shape = "round"
  6. [[fruit.variety]]
  7. name = "red delicious"
  8. [[fruit.variety]]
  9. name = "granny smith"
  10. [[fruit]]
  11. name = "banana"
  12. [[fruit.variety]]
  13. name = "plantain"

This is equivalent to the following JSON structure:

  1. {
  2. "fruit": [
  3. {
  4. "name": "apple",
  5. "physical": {
  6. "color": "red",
  7. "shape": "round"
  8. },
  9. "variety": [
  10. { "name": "red delicious" },
  11. { "name": "granny smith" }
  12. ]
  13. },
  14. {
  15. "name": "banana",
  16. "variety": [
  17. { "name": "plantain" }
  18. ]
  19. }
  20. ]
  21. }

Attempting to define a regular table using an already defined array name will throw a parse error:

  1. # Invalid TOML
  2. [[fruit]]
  3. name = "apple"
  4. [[fruit.variety]]
  5. name = "red delicious"
  6. # Conflicts with above
  7. [fruit.variety]
  8. name = "granny smith"