v1.0.0
Opublikowano dnia 1/11/2021 r. – Wersja tekstowa

TOML v1.0.0

Tom's Obvious, Minimal Language.

Autorzy: Tom Preston-Werner, Pradyun Gedam, i in.

Cele

TOML dąży do tego, żeby był minimalnym formatem dla plików konfiguracji, który jest łatwy do czytania z powodu oczywistej semantyki. TOML jest zaprojektowany do tego, by jednoznacznie odpowiadał tablicy asocjacyjnej. TOML powinien być łatwy do przetwarzania na struktury danych w wielu różnych językach.

Specyfikacja

  • W TOML-u ważna jest wielkość liter.
  • Plik TOML musi być prawidłowym dokumentem Unicode, zakodowanym w UTF-8.
  • Białe znaki to tabulatory (0x09) i spacje (0x20).
  • Łamania linii to LF (0x0A) i CRLF (0x0D 0x0A).

Komentarz

Kratka oznacza, że dalsza część linijki to komentarz, chyba że w środku ciągu znakowego.

# To jest komentarz na całą linijkę
klucz = "wartość"  # To jest komentarz na końcu linijki
inne = "# To nie jest komentarz"

Znaki kontrolne inne niż tabulatory (od U+0000 do U+0008, od U+000A do U+001F, U+007F) nie mogą się pojawić w komentarzu.

Para klucz/wartość

Podstawowym elementem konstrukcji dokumentu TOML jest para klucz/wartość.

Klucze są po lewej stronie znaku równości, a wartości po prawej. Białe znaki są ignorowane wokół nazw kluczy i wartości. Klucz, znak równości, i wartość muszą się pojawić na tej samej linii (chociaż niektóre wartości można rozdzielić na kilka linii).

klucz = "wartość"

Wartości muszą mieć jeden z tych typów.

Nieokreślone wartości są nieprawidłowe:

klucz = # NIEPRAWIDŁOWE

Musi być łamanie linii (lub koniec pliku) po parze klucz/wartość. (zob. Tabela w linii dla wyjątków).

imie = "Tom" nazwisko = "Preston-Werner" # NIEPRAWIDŁOWE

Klucze

Klucz może być prosty, w cudzysłowie, lub przedzielony kropkami.

Klucze proste mogą tylko zawierać litery ASCII, cyfry ASCII, podłogi i myślniki (A-Za-z0-9_-). Zauważ, że klucze proste mogą się składać tylko z cyfr ASCII, np. 1234, ale zawsze są interpretowane jako ciągi znaków.

klucz = "wartość"
klucz_prosty = "wartość"
klucz-prosty = "wartość"
1234 = "wartość"

Klucze w cudzysłowie przestrzegają tych samych reguł, co podstawowe ciągi znaków lub literały znakowe i pozwalają używania dużo szerszego zakresu nazw kluczy. Najlepiej używać tylko kluczy prostych, chyba że to jest absolutnie konieczne.

"127.0.0.1" = "wartość"
"kodowanie znaków" = "wartość"
"zɔnlʞ" = "wartość"
'klucz2' = "wartość"
'"wartość" w cudzysłowie' = "wartość"

Klucz prosty nie może być pusty, ale można używać pustych kluczy w cudzysłowie (chociaż jest to niezalecane).

= "brak nazwy klucza"  # NIEPRAWIDŁOWE
"" = "puste"           # PRAWIDŁOWE, ale niezalecane
'' = 'puste'           # PRAWIDŁOWE, ale niezalecane

Klucze przedzielone kropkami to sekwencje kluczy prostych lub w cudzysłowie złączonych kropką. To pozwala na grupowanie z sobą podobnych właściwości:

nazwa = "Pomarańcza"
fizyczne.kolor = "pomarańczowy"
fizyczne."kształt" = "okrągłe"
witryna."google.com" = true

W świecie JSON to dałoby poniższą strukturę:

{
  "nazwa": "Pomarańcza",
  "fizyczne": {
    "kolor": "pomarańczowy",
    "kształt": "okrągłe"
  },
  "witryna": {
    "google.com": true
  }
}

Szczegóły nt. tabel definiowanych przez klucze przedzielone kropkami znajdują się w sekcji Tabela poniżej.

Białe znaki wokół części oddzielanych kropkami są ignorowane, jednak najlepiej nie używać dodatkowych białych znaków:

owoc.nazwa = "banan"     # tak wygląda najlepiej
owoc. kolor = "żółty"    # to samo, co owoc.kolor
owoc . smak = "bananowy" # to samo, co owoc.smak

Wcięcia są traktowane jak białe znaki i ignorowane.

Nie można definiować jednego klucza wiele razy:

# NIE RÓB TEGO
imie = "Tom"
imie = "Pradyun"

Zauważ, że klucze proste i w cudzysłowie są takie same:

# TO NIE ZADZIAŁA
pisownia = "ulubione"
"pisownia" = "ulóbione"

Dopóki klucz nie został zdefiniowany bezpośrednio, możesz wpisać do niego i do nazw w nim:

# To zamienia wartość klucza "owoc" na tabelę
owoc.jablko.gladki = true

# Więc później możesz dodać do tabeli "owoc" w ten spsoób:
owoc.pomarancza = 2
# PONIŻSZE JEST NIEPRAWIDŁOWE

# To definiuje wartość owoc.jablko jako liczbę całkowitą.
owoc.jablko = 1

# Ale potem traktuje owoc.jablko jako tabelę.
# Nie możesz zamienić liczby całkowitej na tabelę.
owoc.jablko.gladki = true

Niezalecane jest definiowanie kluczy przedzielonych kropkami w niewłaściwej kolejności.

# POPRAWNE, LECZ NIEZALECANE

jablko.typ = "owoc"
pomarancza.typ = "owoc"

jablko.skorka = "cienka"
pomarancza.skorka = "gruba"

jablko.kolor = "czerwony"
pomarancza.kolor = "pomarańczowy"
# ZALECANE

jablko.typ = "owoc"
jablko.skorka = "cienka"
jablko.kolor = "czerwony"

pomarancza.typ = "owoc"
pomarancza.skorka = "gruba"
pomarancza.kolor = "pomarańczowy"

Ponieważ klucze proste mogą być złożone jedynie z cyfr ASCII, można napisać klucze, które wyglądają jak liczby zmiennoprzecinkowe, ale są dwuczęściowymi kluczami przedzielonymi kropkami. Nie rób tego, chyba że masz do tego dobry powód (na pewno nie masz).

3.14159 = "pi"

Powyższy TOML odpowiada JSON-owi poniżej.

{ "3": { "14159": "pi" } }

Ciąg znakowy

Są cztery sposoby, aby wyrazić ciągi znakowe: podstawowy, wieloliniowy podstawowy, dosłowny i wieloliniowy dosłowny. Wszystkie ciągi znakowe muszą zawierać prawidłowe znaki UTF-8.

Podstawowe ciągi znakowe są otoczone cudzysłowami ("). Dowolny znak Unicode może być użyty, oprócz tych, które wymagają ucieczki: cudzysłów, ukośnik odwrotny, i znaki kontrolne inne niż tabulatory (od U+0000 do U+0008, od U+000A do U+001F, U+007F).

cz = "Jestem ciągiem znaków. \"Możesz mnie zacytować\". Name\tJos\u00E9\nLocation\tSF."

Dla wygody niektóre popularne znaki mają kompaktowe sekwencje ucieczki.

\b         - backspace        (U+0008)
\t         - tabulator        (U+0009)
\n         - koniec linii     (U+000A)
\f         - form feed        (U+000C)
\r         - powrót karetki   (U+000D)
\"         - cudzysłów        (U+0022)
\\         - ukośnik odwrotny (U+005C)
\uXXXX     - unicode          (U+XXXX)
\UXXXXXXXX - unicode          (U+XXXXXXXX)

Każdy znak Unicode może mieć ucieczkę w formie \uXXXX lub \UXXXXXXXX. Kody ucieczki muszą być poprawnymi wartościami skalarnymi Unicode.

Wszystkie inne sekwencje ucieczki niepodane powyżej są zarezerwowane; jeśli są użyte, TOML powinien wypisać błąd.

Czasami musisz wyrazić fragmenty tekstu (np. pliki tłumaczenia) lub chcesz podzielić bardzo długi ciąg znaków na wiele linijek. TOML to ułatwia.

Wieloliniowe podstawowe ciągi znakowe są otoczone trzema cudzysłowami z każdej strony i pozwalają na łamania linii. Łamanie linii tuż po otwartym ograniczniku zostanie usunięte. Inne białe znaki i łamania linii pozostają bez zmian.

cz1 = """
Wlazł kotek na płotek
I mruga, i mruga."""

Parsery TOML mogą wybrać styl łamań linii odpowiedni dla platformy.

# Na systemie Unix powyższy ciąg wieloliniowy będzie najprawdopodobniej taki sam, co:
cz2 = "Wlazł kotek na płotek\nI mruga, i mruga."

# Na Windowsie będzie najprawdopodobniej taki sam, co:
cz3 = "Wlazł kotek na płotek\r\nI mruga, i mruga."

Do zapisywania długich ciągów bez dodatkowych spacji użyj "ukośnika odwrotnego na końcu linii". Jeśli ostatni znak na linii inny niż biały znak jest \ niebędący częścią sekwencji ucieczki, będzie usunięty wraz ze wszystkimi białymi znakami (uwzględniając łamania linii) aż do kolejnego niebiałego znaku lub ogranicznika zamykającego. Wszystkie sekwencje ucieczki, które są prawidłowe dla podstawowych ciągów znaków, są też prawidłowe dla wieloliniowych podstawowych ciągów znaków.

# Te ciągi znakowe są takie same co do bajtów:
cz1 = "Pchnąć w tę łódź jeża lub ośm skrzyń fig."

cz2 = """
Pchnąć w tę \


  łódź jeża lub \
    ośm skrzyń fig."""

cz3 = """\
      Pchnąć w tę \
      łódź jeża lub \
      ośm skrzyń fig.\
      """

Dowolny znak Unicode może być użyty oprócz tych, co wymagają ucieczki: ukośnik odwrotny, i znaki kontrolne inne niż tabulatory, końce linii i powroty karetki (od U+0000 do U+0008, U+000B, U+000C, od U+000E do U+001F, U+007F).

Możesz zapisać cudzysłów lub dwa sąsiadujące ze sobą gdziekolwiek w wieloliniowym podstawowym ciągu znakowym. Można też je zapisać wewnątrz ograniczników.

cz4 = """Tu są dwa cudzysłowy: "". Wystarczająco proste."""
# cz5 = """Tu są trzy cudzysłowy: """."""  # NIEPRAWIDŁOWE
cz5 = """Tu są trzy cudzysłowy: ""\"."""
cz6 = """Tu jest piętnaście cudzysłowów: ""\"""\"""\"""\"""\"."""

# "To" - powiedziała, "jest tylko bezcelową wypowiedzią".
cz7 = """"To" - powiedziała, "jest tylko bezcelową wypowiedzią"."""

Jeśli często wpisujesz ścieżki Windowsa lub wyrażenia regularne, konieczność ucieczki ukośników odwrotnych szybko staje się żmudna i skłonna do błędów. Aby pomóc, TOML wspiera literały znakowe, które w ogóle nie pozwalają na ucieczki.

Literały znakowe są otoczone pojedynczymi cudzysłowami. Jak podstawowe ciągi znakowe, muszą się pojawić w jednej linii:

# Widzisz to, co otrzymasz.
winsciezka   = 'C:\Users\nodejs\templates'
winsciezka2  = '\\ServerX\admin$\system32\'
wcudzyslowie = 'Tom "Dubs" Preston-Werner'
regex        = '<\i\c*\s*>'

Ponieważ nie ma ucieczek, nie ma sposobu na napisanie cudzysłowu pojedynczego wewnątrz literału znakowego w cudzysłowie pojedynczym. Na szczęście TOML wspiera wieloliniową wersję literałów znakowych, która rozwiązuje ten problem.

Wieloliniowe literały znakowe są otoczone trzema cudzysłowami pojedynczymi z każdej strony i zezwalają na łamania linii. Jak literały znakowe, nie ma tu w ogóle ucieczek. Łamanie linii tuż po ograniczniku otwierającym zostanie usunięte. Pozostała treść między ogranicznikami jest interpretowana, tak jak jest, bez modyfikacji.

regex2 = '''\d{2} telefon[uy]? Apple('a)?'''
linie  = '''
Pierwsze łamanie linii
jest usunięte w surowych
literałach znakowych.
    Pozostałe białe
    znaki są zachowane.
'''

Możesz zapisać 1 lub 2 cudzysłowy pojedyncze w wieloliniowym literale znakowym, ale sekwencje co najmniej trzech cudzysłowów pojedynczych nie są dozwolone.

quot15 = '''Tu jest piętnaście cudzysłowów: """""""""""""""'''

# apos15 = '''Tu jest piętnaście apostrofów: ''''''''''''''''''  # NIEPRAWIDŁOWE
apos15 = "Tu jest piętnaście apostrofów: '''''''''''''''"

# 'To jest nadal bezcelowe' - powiedziała.
str = ''''To jest nadal bezcelowe' - powiedziała.'''

Znaki kontrolne inne niż tabulator nie są dozwolone w literale znakowym. Dlatego dla danych binarnych, zalecane jest użycie kodowania Base64 lub innego odpowiedniego kodowania ASCII czy UTF-8. Operowanie takim kodowaniem będzie specyficzne dla aplikacji.

Liczba całkowita

Charakter liczb całkowitych jest widoczny z nazwy. Liczby dodatnie mogą być poprzedzone plusem. Liczby ujemne są poprzedzone minusem.

lc1 = +99
lc2 = 42
lc3 = 0
lc4 = -17

Dla dużych liczb można użyć podłóg między cyframi, aby ułatwić ich czytanie. Każda podłoga musi być otoczona co najmniej jedną cyfrą z każdej strony.

lc5 = 1_000
lc6 = 5_349_221
lc7 = 53_49_221  # Grupowanie według indyjskiego systemu liczbowego
lc8 = 1_2_3_4_5  # POPRAWNE, ale niezalecane

Początkowe zera nie są dozwolone. Wartości całkowite -0 i +0 są poprawne i są identyczne z zerem bez znaku.

Liczby nieujemne mogą być wyrażone w postaci szesnastkowej, ósemkowej lub dwójkowej. W tych formatach początkowy + nie jest dozwolony, a początkowe zera są dozwolone (po prefiksie). W wartościach szesnastkowych wielkość liter nie jest ważna. Podłogi są dozwolone między cyframi (ale nie między prefiksem a wartością).

# szesnastkowe z prefiksem `0x`
hex1 = 0xDEADBEEF
hex2 = 0xdeadbeef
hex3 = 0xdead_beef

# ósemkowe z prefiksem `0o`
oct1 = 0o01234567
oct2 = 0o755 # użyteczne dla uprawnień plików na Unixie

# dwójkowe z prefiksem `0b`
bin1 = 0b11010110

Dowolne liczby całkowite 64-bitowe ze znakiem (od -2^63 do 2^63-1) powinny być przyjmowane i przetwarzane bezstratnie. Jeśli liczby nie da się przedstawić bezstratnie, trzeba wypisać błąd.

Liczba zmiennoprzecinkowa

Liczby zmiennoprzecinkowe powinny być zaimplementowane jako wartości 64-bitowe zgodne z IEEE 754.

Liczba zmiennoprzecinkowa składa się z części całkowitej (która przestrzega tych samych reguł, co liczby całkowite), po której następuje część ułamkowa lub wykładnicza. Jeśli występuje zarówno część ułamkowa, jak i wykładnicza, część ułamkowa musi poprzedzać część wykładniczą.

# ułamki
lzp1 = +1.0
lzp2 = 3.1415
lzp3 = -0.01

# notacja naukowa
lzp4 = 5e+22
lzp5 = 1e06
lzp6 = -2E-2

# oba
lzp7 = 6.626e-34

Część ułamkowa to kropka, po której następuje co najmniej jedna cyfra.

Część wykładnicza składa się z litery E (wielkiej lub małej), po której jest część całkowita (która przestrzega tych samych reguł, co liczba całkowita, ale może zawierać zera na początku).

Jeśli jest użyty separator dziesiętny, po każdej stronie musi być przynajmniej jedna cyfra.

# NIEPRAWIDŁOWE LICZBY ZMIENNOPRZECINKOWE
nieprawidlowa_liczba_zp_1 = .7
nieprawidlowa_liczba_zp_2 = 7.
nieprawidlowa_liczba_zp_3 = 3.e+20

Podobnie do liczb całkowitych można używać podłóg, aby ułatwić czytanie. Każda podłoga musi być otoczona co najmniej jedną cyfrą.

lzp8 = 224_617.445_991_228

Wartości zmiennoprzecinkowe -0.0 i +0.0 są poprawne i powinny odpowiadać wartościom według IEEE 754.

Specjalne wartości zmiennoprzecinkowe też mogą być wyrażone. Zawsze są pisane małymi literami.

# nieskończoność
szp1 = inf  # nieskończoność dodatnia
szp2 = +inf # nieskończoność dodatnia
szp3 = -inf # nieskończoność ujemna

# nie-liczba
szp4 = nan  # właściwe kodowanie sNaN/qNaN jest specyficzne dla implementacji
szp5 = +nan # to samo, co `nan`
szp6 = -nan # poprawne, właściwe kodowanie jest specyficzne dla implementacji

Wartość logiczna

Wartości logiczne to po prostu słowa, do których jesteś przyzwyczajony. Zawsze pisane małymi literami.

log1 = true
log2 = false

Data i czas z przesunięciem

Aby jednoznacznie przedstawić specyficzny moment w czasie, możesz użyć daty i czasu z przesunięciem, sformatowanego zgodnie z RFC 3339.

dcp1 = 1979-05-27T07:32:00Z
dcp2 = 1979-05-27T00:32:00-07:00
dcp3 = 1979-05-27T00:32:00.999999-07:00

Aby poprawić czytelność, można zastąpić ogranicznik T między datą a czasem spacją (co jest dozwolone według sekcji 5.6 RFC 3339).

dcp4 = 1979-05-27 07:32:00Z

Precyzja co do milisekundy jest wymagana. Większa precyzja ułamków sekund jest specyficzna dla implementacji. Jeśli wartość jest bardziej precyzyjna, niż jest to wspierane przez implementację, dodatkowa precyzja musi być obcięta, a nie zaokrąglona.

Data i czas lokalny

Jeśli pominiesz przesunięcie z daty i czasu sformatowanego według RFC 3339, będzie to reprezentować datę i czas bez relacji do przesunięcia lub strefy czasowej. Nie może być przekonwertowane na moment bez dodatkowych informacji. Konwersja na moment, jeśli wymagana, jest specyficzna dla implementacji.

dcl1 = 1979-05-27T07:32:00
dcl2 = 1979-05-27T00:32:00.999999

Precyzja co do milisekundy jest wymagana. Większa precyzja ułamków sekund jest specyficzna dla implementacji. Jeśli wartość jest bardziej precyzyjna, niż jest to wspierane przez implementację, dodatkowa precyzja musi być obcięta, a nie zaokrąglona.

Data lokalna

Jeśli podasz tylko część reprezentującą datę z daty i czasu sformatowanego według RFC 3339, będzie to reprezentować cały dzień bez relacji do przesunięcia lub strefy czasowej.

dl1 = 1979-05-27

Czas lokalny

Jeśli podasz tylko część reprezentującą czas z daty i czasu sformatowanego według RFC 3339, będzie to reprezentować daną porę dnia bez relacji do określonego dnia, przesunięcia, czy strefy czasowej.

cl1 = 07:32:00
cl2 = 00:32:00.999999

Precyzja co do milisekundy jest wymagana. Większa precyzja ułamków sekund jest specyficzna dla implementacji. Jeśli wartość jest bardziej precyzyjna, niż jest to wspierane przez implementację, dodatkowa precyzja musi być obcięta, a nie zaokrąglona.

Lista

Listy są otoczone nawiasami kwadratowymi i zawierają wartości. Białe znaki są ignorowane. Elementy są oddzielone przecinkami. Listy mogą zawierać wartości tych samych typów danych, co dozwolone w parach klucz/wartość. Wartości różnych typów mogą być mieszane.

liczby_calk = [ 1, 2, 3 ]
kolory = [ "red", "yellow", "green" ]
zagniezdzone_listy_liczb = [ [ 1, 2 ], [3, 4, 5] ]
zagniezdzona_lista_mieszana = [ [ 1, 2 ], ["a", "b", "c"] ]
lista_ciagow_znakowych = [ "all", 'strings', """are the same""", '''type''' ]

# Dozwolone są listy typu mieszanego
liczby = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
wnoszacy_wklad = [
  "Foo Bar <foo@example.com>",
  { nazwa = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
]

Listy mogą zajmować wiele linijek. Końcowy przecinek jest dozwolony po ostatniej wartości listy. Dowolna liczba łamań linii może poprzedzać wartości, przecinki i nawias zamykający. Wcięcia między wartościami listy i przecinkami są traktowane jako białe znaki i ignorowane.

licz_calk2 = [
  1, 2, 3
]

licz_calk3 = [
  1,
  2, # to jest OK
]

Tabela

Tabele (znane też jako tablice mieszające lub słowniki) są kolekcjami par klucz/wartość. Są zdefiniowane nagłówkami z nawiasami kwadratowymi, występującymi samodzielnie w linijce. Można odróżnić nagłówki od list tym, że listy jedynie zawierają wartości.

[tabela]

Pod tym do następnego nagłówka lub końca pliku są pary klucz/wartość danej tabeli. Nie jest gwarantowane, żeby pary klucz/wartość w tabelach miały określoną kolejność.

[tabela-1]
klucz1 = "jakiś ciąg znaków"
klucz2 = 123

[tabela-2]
klucz1 = "inny ciąg znaków"
klucz2 = 456

Reguły nazywania tabel są takie same jak kluczy (zobacz definicję kluczy powyżej).

[pies."tater.man"]
typ.nazwa = "mops"

W świecie JSON to dałoby poniższą strukturę:

{ "pies": { "tater.man": { "typ": { "nazwa": "mops" } } } }

Białe znaki wokół klucza są ignorowane, jednak najlepiej nie używać dodatkowych białych znaków.

[a.b.c]            # tak jest najlepiej
[ d.e.f ]          # to samo, co [d.e.f]
[ g .  h  . i ]    # to samo, co [g.h.i]
[ j . "ʞ" . 'l' ]  # to samo, co [j."ʞ".'l']

Wcięcia są traktowane jako białe znaki i ignorowane.

Nie trzeba definiować nadtabel, jeśli tego nie chcesz. TOML wie, jak to zrobić za Ciebie.

# [x] nie
# [x.y] potrzebujesz
# [x.y.z] tego,
[x.y.z.w] # aby to działało

[x] # Definiowanie nadtabeli później jest OK

Puste tabele są dozwolone i po prostu nie mają w sobie par klucz/wartość.

Tak jak kluczy, nie możesz definiować tabeli więcej niż raz; to jest nieprawidłowe.

# NIE RÓB TEGO

[owoc]
jablko = "czerwone"

[owoc]
pomarancza = "pomarańczowa"
# TEGO TEŻ NIE RÓB

[owoc]
jablko = "czerwone"

[owoc.jablko]
faktura = "gładka"

Definiowanie tabel poza kolejnością jest niezalecane.

# POPRAWNE, ALE NIEZALECANE
[owoc.jablko]
[zwierze]
[owoc.pomarancza]
# ZALECANE
[owoc.jablko]
[owoc.pomarancza]
[zwierze]

Tabela najwyższego poziomu, zwana także tabelą główną, zaczyna się na początku dokumentu i się kończy tuż przed pierwszym nagłówkiem tabeli (lub końcem pliku). W przeciwieństwie do innych tabel nie ma nazwy i nie może zostać przeniesiona.

# Tabela główna się zaczyna.
imie = "Fido"
rasa = "mops"

# Tabela główna się kończy.
[wlasciciel]
imie_nazwisko = "Regina Dogman"
czlonek_od = 1999-08-04

Klucze przedzielone kropkami tworzą i definiują tabelę dla każdego klucza oprócz ostatniego, zakładając, że takie tabele nie były wcześniej tworzone.

owoc.jablko.kolor = "red"
# Definiuje tabelę owoc
# Definiuje tabelę owoc.jablko

owoc.jablko.smak.slodki = true
# Definiuje tabelę owoc.jablko.smak
# owoc i owoc.jablko zostały już stworzone

Ponieważ tabel nie można zdefiniować więcej niż raz, ponowne definiowanie takich tabel za pomocą [naglowka] nie jest dozwolone. Tak samo używanie kluczy przedzielonych kropkami już zdefiniowanych w formie [tabeli] nie jest dozwolone. Jednak forma [tabeli] może być użyta do zdefiniowana podtabel w tabelach zdefiniowanych kluczami przedzielonymi kropkami.

[owoc]
jablko.kolor = "red"
jablko.smak.slodki = true

# [owoc.jablko]  # NIEPOPRAWNE
# [owoc.jablko.smak]  # NIEPOPRAWNE

[owoc.jablko.faktura]  # możesz dodać podtabele
gladkie = true

Tabela w jednej linii

Tabele w linii (lub tabele jednoliniowe) zapewniają bardziej kompaktową składnię do wyrażania tabel. Są szczególnie użyteczne dla grupowanych danych, które inaczej mogą szybko stać się rozwlekłe. Tabele w linii są w pełni zdefiniowane wewnątrz nawiasów klamrowych: { i }. Wewnątrz klamer można umieścić dowolną ilość par klucz/wartość oddzielonych przecinkami. Wszelkie wartości typów są dozwolone, łącznie z tabelami jednoliniowymi.

Zamierzony wygląd tabel jednoliniowych jest widoczny z nazwy. Końcowy przecinek nie jest dozwolony po ostatniej parze klucz/wartość w tabeli jednoliniowej. Nie można używać łamań linii między klamrami, chyba że są dozwolone w wartości. Nawet wtedy jest stanowczo niezalecane łamanie tabeli w linii na wiele linijek. Jeśli i tak chcesz korzystać z możliwości łamania wartości na wiele linijek, powinieneś używać standardowych tabel.

nazwa = { imie = "Tom", nazwisko = "Preston-Werner" }
punkt = { x = 1, y = 2 }
zwierze = { typ.nazwa = "mops" }

Powyższe tabele są identyczne z poniższymi standardowymi definicjami tabel:

[nazwa]
imie = "Tom"
nazwisko = "Preston-Werner"

[punkt]
x = 1
y = 2

[zwierze]
typ.nazwa = "mops"

Tabele jednoliniowe są samodzielne i definiują wszystkie zawarte klucze i podtabele; nie można ich dodać poza klamrami.

[produkt]
typ = { nazwa = "Gwóźdź" }
# typ.jadalny = false  # NIEPRAWIDŁOWE

Podobnie nie można używać tabel jednoliniowych do dodawania kluczy lub podtabel do już zdefiniowanej tabeli.

[produkt]
typ.nazwa = "Gwóźdź"
# typ = { jadalny = false }  # NIEPRAWIDŁOWE

Lista tabel

Ostatnia składnia, która nie została opisana, zezwala na pisanie list tabel. Takie można wyrazić, używając nazwy nagłówka w podwójnych nawiasach kwadratowych. Pierwsze wystąpienie danego nagłówka definiuje listę i jej pierwszy element tabelaryczny, a każde kolejne wystąpienie tego nagłówka definiuje nowy element tabelaryczny na tej liście. Tabele są dodawane do listy w kolejności, w jakiej się na nie napotka.

[[produkty]]
nazwa = "Młotek"
sku = 738594937

[[produkty]]  # pusta tabela na liście

[[produkty]]
nazwa = "Gwóźdź"
sku = 284758393

kolor = "szary"

W świecie JSON to dałoby poniższą strukturę.

{
  "produkty": [
    { "nazwa": "Młotek", "sku": 738594937 },
    { },
    { "nazwa": "Gwóźdź", "sku": 284758393, "kolor": "szary" }
  ]
}

Każde odwołanie do listy tabel wskazuje na ostatnio zdefiniowany element listy. To pozwala na definiowanie podtabel, a także podlist tabel, wewnątrz ostatniej tabeli.

[[owoce]]
nazwa = "jabłko"

[owoce.fizyczne]  # podtabela
kolor = "czerwony"
ksztalt = "okrągły"

[[owoce.odmiany]]  # zagnieżdżona lista tabel
nazwa = "red delicious"

[[owoce.odmiany]]
nazwa = "granny smith"


[[owoce]]
nazwa = "banan"

[[owoce.odmiany]]
nazwa = "błogosława"

Powyższy TOML odpowiada JSON-owi poniżej.

{
  "owoce": [
    {
      "nazwa": "jabłko",
      "fizyczne": {
        "kolor": "czerwony",
        "ksztalt": "okrągły"
      },
      "odmiany": [
        { "nazwa": "red delicious" },
        { "nazwa": "granny smith" }
      ]
    },
    {
      "nazwa": "banan",
      "odmiany": [
        { "nazwa": "błogosława" }
      ]
    }
  ]
}

Jeśli rodzic tabeli czy listy tabel jest elementem tabelarycznym, ten element musi być poprzednio zdefiniowany, zanim można zdefiniować element potomny. Próby odwrócenia tej kolejności muszą wypisać błąd podczas przetwarzania.

# NIEPRAWIDŁOWY DOKUMENT TOML
[owoc.fizyczne]  # podtabela, ale do którego elementu-rodzica ma należeć?
kolor = "czerwony"
ksztalt = "okrągły"

[[owoc]]  # parser musi wypisać błąd, bo odkrył, że "owoc" jest listą,
          # a nie tabelą
nazwa = "jabłko"

Próba dołączenia do statycznie zdefiniowanej listy, nawet jeśli ta lista jest pusta, musi wypisać błąd podczas przetwarzania.

# NIEPRAWIDŁOWY DOKUMENT TOML
owoce = []

[[owoce]] # Niedozwolone

Próby zdefiniowania normalnej tabeli z tą samą nazwą, co już jest ustalone jako lista, musi wypisać błąd podczas przetwarzania. Tak samo jest w przypadku próby ponownej definicji normalnej tabeli jako lista.

# NIEPRAWIDŁOWY DOKUMENT TOML
[[owoce]]
nazwa = "jabłko"

[[owoce.odmiany]]
nazwa = "red delicious"

# NIEPRAWIDŁOWE: Ta tabela konfliktuje z poprzednią listą tabel
[owoce.odmiany]
nazwa = "granny smith"

[owoce.fizyczne]
kolor = "czerwony"
ksztalt = "okrągły"

# NIEPRAWIDŁOWE: Ta lista tabel konfliktuje z poprzednią tabelą
[[owoce.fizyczne]]
kolor = "zielony"

Tam, gdzie to odpowiednie, można użyć tabel jednoliniowych:

punkty = [ { x = 1, y = 2, z = 3 },
           { x = 7, y = 8, z = 9 },
           { x = 2, y = 4, z = 8 } ]

Rozszerzenie nazwy pliku

Pliki TOML powinny używać rozszerzenia .toml.

Typ MIME

Kiedy przesyłasz pliki TOML przez internet, odpowiednim typem MIME jest application/toml.

Gramatyka ABNF

Formalny opis składni TOML-a jest dostępny jako osobny plik ABNF.