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. Spis treści ----------- - [Specyfikacja](#specyfikacja) - [Komentarz](#komentarz) - [Para klucz/wartość](#para-kluczwartość) - [Klucze](#klucze) - [Ciąg znakowy](#ciąg-znakowy) - [Liczba całkowita](#liczba-całkowita) - [Liczba zmiennoprzecinkowa](#liczba-zmiennoprzecinkowa) - [Wartość logiczna](#wartość-logiczna) - [Data i czas z przesunięciem](#data-i-czas-z-przesunięciem) - [Data i czas lokalny](#data-i-czas-lokalny) - [Data lokalna](#data-lokalna) - [Czas lokalny](#czas-lokalny) - [Lista](#lista) - [Tabela](#tabela) - [Tabela w linii](#tabela-w-jednej-linii) - [Lista tabel](#lista-tabel) - [Rozszerzenie nazwy pliku](#rozszerzenie-nazwy-pliku) - [Typ MIME](#typ-mime) - [Gramatyka ABNF](#gramatyka-abnf) 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. ```toml # 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). ```toml klucz = "wartość" ``` Wartości muszą mieć jeden z tych typów. - [Ciąg znakowy](#ciąg-znakowy) - [Liczba całkowita](#liczba-całkowita) - [Liczba zmiennoprzecinkowa](#liczba-zmiennoprzecinkowa) - [Wartość logiczna](#wartość-logiczna) - [Data i czas z przesunięciem](#data-i-czas-z-przesunięciem) - [Data i czas lokalny](#data-i-czas-lokalny) - [Data lokalna](#data-lokalna) - [Czas lokalny](#czas-lokalny) - [Lista](#lista) - [Tabela w linii](#tabela-w-jednej-linii) Nieokreślone wartości są nieprawidłowe: ```toml klucz = # NIEPRAWIDŁOWE ``` Musi być łamanie linii (lub koniec pliku) po parze klucz/wartość. (zob. [Tabela w linii](#tabela-w-jednej-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. ```toml 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. ```toml "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). ```toml = "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: ```toml 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ę: ```json { "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](#tabela) poniżej. Białe znaki wokół części oddzielanych kropkami są ignorowane, jednak najlepiej nie używać dodatkowych białych znaków: ```toml 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. ```toml # POPRAWNE, LECZ NIEZALECANE jablko.typ = "owoc" pomarancza.typ = "owoc" jablko.skorka = "cienka" pomarancza.skorka = "gruba" jablko.kolor = "czerwony" pomarancza.kolor = "pomarańczowy" ``` ```toml # 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). ```toml 3.14159 = "pi" ``` Powyższy TOML odpowiada JSON-owi poniżej. ```json { "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). ```toml 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]( https://unicode.org/glossary/#unicode_scalar_value). 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. ```toml cz1 = """ Wlazł kotek na płotek I mruga, i mruga.""" ``` Parsery TOML mogą wybrać styl łamań linii odpowiedni dla platformy. ```toml # 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. ```toml # 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. ```toml 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: ```toml # 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. ```toml 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. ```toml 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. ```toml 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. ```toml 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ą). ```toml # 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ą. ```toml # 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ą. ```toml 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. ```toml # 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. ```toml 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]( https://tools.ietf.org/html/rfc3339). ```toml 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). ```toml 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]( https://tools.ietf.org/html/rfc3339), 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. ```toml 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](https://tools.ietf.org/html/rfc3339), będzie to reprezentować cały dzień bez relacji do przesunięcia lub strefy czasowej. ```toml dl1 = 1979-05-27 ``` Czas lokalny ------------ Jeśli podasz tylko część reprezentującą czas z daty i czasu sformatowanego według [RFC 3339](https://tools.ietf.org/html/rfc3339), będzie to reprezentować daną porę dnia bez relacji do określonego dnia, przesunięcia, czy strefy czasowej. ```toml 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. ```toml 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 ", { 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. ```toml 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. ```toml [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ść. ```toml [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](#klucze) powyżej). ```toml [pies."tater.man"] typ.nazwa = "mops" ``` W świecie JSON to dałoby poniższą strukturę: ```json { "pies": { "tater.man": { "typ": { "nazwa": "mops" } } } } ``` Białe znaki wokół klucza są ignorowane, jednak najlepiej nie używać dodatkowych białych znaków. ```toml [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. ```toml # [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. ```toml # POPRAWNE, ALE NIEZALECANE [owoc.jablko] [zwierze] [owoc.pomarancza] ``` ```toml # 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. ```toml # 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. ```toml 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. ```toml [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. ```toml 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: ```toml [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. ```toml [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. ```toml [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. ```toml [[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ę. ```json { "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. ```toml [[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. ```json { "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: ```toml 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][abnf]. [abnf]: https://github.com/toml-lang/toml/blob/1.0.0/toml.abnf