Nette Documentation Preview

syntax
Formát NEON
***********

.[perex]
NEON je lidsky čitelný strukturovaný datový formát. V Nette se používá pro konfigurační soubory. Také se používá pro strukturovaná data, jako jsou nastavení, jazykové překlady atd. [Vyzkoušejte si jej|https://fiddle.nette.org/neon/].

NEON je zkratka pro *Nette Object Notation*. Je méně složitý a nemotorný než XML nebo JSON, ale poskytuje podobné funkce. Je velmi podobný YAML. Hlavní předností je to, že NEON má takzvané [#entity], díky kterým je konfigurace DI služeb [taky sexy |https://gist.github.com/dg/26baf3ce8f29d0f751e9dddfaa06504f]. A umožňuje odsazovat tabulátory.

NEON je postaven od základů tak, aby byl snadno použitelný. Knihovny pro PHP, JavaScript a Python, podporu v editorech a specifikaci formátu najdete na stránce [Nástroje a knihovny |tools].


Syntaxe
=======

Soubor psaný v NEON obvykle představuje pole nebo mapování.


Mapování
--------
Mapování je sada párů klíč-hodnota, v PHP by se řeklo asociativní pole. Každá dvojice je zapsána jako `key: value`, mezera za `:` je nutná. Hodnotou může být cokoliv: řetězec, číslo, boolean, null, sekvence nebo jiné mapování.

```neon
street: 742 Evergreen Terrace
city: Springfield
country: USA
```

V PHP by se stejná struktura zapsala jako:

```php
[ // PHP
	'street' => '742 Evergreen Terrace',
	'city' => 'Springfield',
	'country' => 'USA',
]
```

Tento zápis se označuje jako blokový, protože všechny položky jsou na samostatném řádku a mají stejné odsazení (v tomto případě žádné). NEON podporuje také inline reprezentaci mapování, která je uzavřená do závorek, odsazení nehraje žádnou roli a oddělovačem jednotlivých prvků je buď čárka, nebo nový řádek:

```neon
{street: 742 Evergreen Terrace, city: Springfield, country: USA}
```

Totéž zapsané na více řádcích (na odsazení nezáleží):

```neon
{
	street: 742 Evergreen Terrace
		city: Springfield, country: USA
}
```

Místo <code>: </code> lze alternativně používat `=`, a to jak v blokovém, tak v inline zápisu:

```neon
{street=742 Evergreen Terrace, city=Springfield, country=USA}
```


Sekvence
--------
Sekvence jsou v PHP indexované pole. Zapisují se jako řádky začínající spojovníkem `-` následovaným mezerou. Hodnotou opět může být cokoliv: řetězec, číslo, boolean, null, sekvence nebo jiné mapování.

```neon
- Cat
- Dog
- Goldfish
```

V PHP by se stejná struktura zapsala jako:

```php
[ // PHP
	'Cat',
	'Dog',
	'Goldfish',
]
```

Tento zápis se označuje jako blokový, protože všechny položky jsou na samostatném řádku a mají stejné odsazení (v tomto případě žádné). NEON podporuje také inline reprezentaci sekvence, která je uzavřená do závorek, odsazení nehraje žádnou roli a oddělovačem jednotlivých prvků je buď čárka, nebo nový řádek:

```neon
[Cat, Dog, Goldfish]
```

Totéž zapsané na více řádcích (na odsazení nezáleží):

```neon
[
	Cat, Dog
		Goldfish
]
```

V inline reprezentaci nelze používat odsazující odrážky.


Kombinace
---------
Hodnotami mapování a sekvencí mohou být jiné mapování a sekvence. Hlavní roli hraje úroveň odsazení. V následujícím příkladu má pomlčka použitá k označení položek sekvence větší odsazení než klíč `pets`, takže se položky stávají hodnotou prvního řádku:

```neon
pets:
   - Cat
   - Dog
cars:
   - Volvo
   - Skoda
```

V PHP by se stejná struktura zapsala jako:

```php
[ // PHP
	'pets' => [
		'Cat',
		'Dog',
	],
	'cars' => [
		'Volvo',
		'Skoda',
	],
]
```

Lze kombinovat blokový a inline zápis:

```neon
pets: [Cat, Dog]
cars: [
	Volvo,
	Skoda,
]
```

Uvnitř inline zápisu již nelze používat zápis blokový, tohle nefunguje:

```neon
item: [
	pets:
	 - Cat     # TOHLE NELZE!!!
	 - Dog
]
```

V předchozím případě jsme zapsali mapování, jehož prvky byly sekvence, teď to zkusíme obráceně a vytvoříme sekvenci obsahující mapování:

```neon
-
	name: John
	age: 35
-
	name: Peter
	age: 28
```

Není nutné, aby odrážky byly na samostatných řádcích, lze je umístit i tímto způsobem:

```neon
- name: John
  age: 35
- name: Peter
  age: 28
```

Je na vás, jestli klíče zarovnáte do sloupce pomocí mezer nebo použijete tabulátor.

Protože v PHP se používá pro mapování i sekvence stejná struktura, tedy pole, lze obojí sloučit. Odsazení je tentokrát stejné:

```neon
- Cat
street: 742 Evergreen Terrace
- Goldfish
```

V PHP by se stejná struktura zapsala jako:

```php
[ // PHP
	'Cat',
	'street' => '742 Evergreen Terrace',
	'Goldfish',
]
```

Položka bez klíče dostane celočíselný klíč o jedna větší než největší celočíselný klíč před ní, stejně jako v PHP. Takže `{5: Cat, Dog}` dá položce `Dog` klíč 6.


Řetězce
-------
Řetězce v NEON lze uzavřít do jednoduchých i dvojitých uvozovek. Ale jak vidíte, mohou být také bez uvozovek.

```neon
- Řetězec v NEON bez uvozovek
- 'Řetězec v NEON v jednoduchých uvozovkách'
- "Řetězec v NEON ve dvojitých uvozovkách"
```

Pokud řetězec obsahuje znaky `` # " ' ` , : = - [ ] { } ( ) ``, které lze zaměnit s NEON syntaxí, je potřeba jej uzavřít do uvozovek. Doporučujeme použít jednoduché uvozovky, protože v nich se nepoužívá escapování. Pokud potřebujete v takovém řetězci zapsat uvozovku, zdvojte ji:

```neon
'Uvozovka '' uvnitř řetězce v jednoduchých uvozovkách'
```

Dvojité uvozovky umožňují používat escape sekvence pro zápis speciálních znaků pomocí zpětných lomítek `\`. Podporovány jsou všechny escape sekvence jako u formátu JSON a navíc `\_`, což je nedělitelná mezera, tedy `\u00A0`.

```neon
- "\t \n \r \f \b \" \\ \/ \_"
- "\u00A9"
```

Existují další případy, kdy je potřeba uzavřít řetězce do uvozovek:
- začínají či končí mezerami
- vypadají jako čísla, booleany, nebo null
- NEON by je chápal jako [#datum]


Víceřádkové řetězce
-------------------

Víceřádkový řetězec začíná a končí trojitou uvozovkou na samostatných řádcích. Odsazení prvního neprázdného řádku se odstraní ze všech řádků:

```neon
'''
	první řádek
		druhý řádek
	třetí řádek
	'''
```

V PHP bychom totéž napsali jako:

```php
"první řádek\n\tdruhý řádek\ntřetí řádek" // PHP
```

Řádek odsazený méně než první neprázdný řádek si své odsazení ponechá celé. Řádek jen z mezer nebo tabulátorů není prázdný, takže pokud je první, určí odsazení on.

Escapovací sekvence fungují jen u řetězců uvozených dvojitými uvozovkami místo apostrofů:

```neon
"""
	Copyright \u00A9
"""
```

Zpětné lomítko na konci řádku ho nespojí s dalším řádkem, v řetězci zůstane.


Čísla
-----
NEON rozumí číslům zapsaným v tzv. vědecké notaci a také číslům v binární, osmičkové a hexadecimální soustavě:

```neon
- 12         # celé číslo
- 12.3       # float
- +1.2e-34   # exponenciální číslo

- 0b11010    # binární číslo
- 0o666      # osmičkové číslo
- 0x7A       # hexa číslo
```

Předpony `0b`, `0o` a `0x` se píšou malými písmeny a bez znaménka, takže `0X10` a `-0x1` jsou řetězce. Úvodní nuly neznamenají osmičkové číslo: `0777` je 777. Podtržítka mezi číslicemi povolená nejsou, `1_000` je řetězec.


Nulls
-----
Null lze v NEON vyjádřit pomocí `null` nebo neuvedením hodnoty. Povoleny jsou také varianty s velkým prvním nebo velkými všemi písmeny.

```neon
a: null
b:
```


Booleans
--------
Logické hodnoty jsou v NEON vyjádřeny pomocí `true` / `false` nebo `yes` / `no`. Povoleny jsou také varianty s velkým prvním nebo velkými všemi písmeny.

```neon
[true, TRUE, True, false, yes, no]
```

Slova `on` a `off`, která YAML 1.1 čte jako logické hodnoty, jsou v NEONu obyčejné řetězce. .{data-version:3.4.0}


Datum
-----
NEON používá k vyjádření dat následující formáty a automaticky je převede na objekty `DateTimeImmutable`:

```neon
- 2016-06-03                  # datum
- 2016-06-03 19:00:00         # datum & čas
- 2016-06-03 19:00:00.1234    # datum & mikročas
- 2016-06-03 19:00:00 +0200   # datum & čas & zóna
- 2016-06-03 19:00:00 +02:00  # datum & čas & zóna
- 2016-06-03T19:00:00Z        # ISO 8601 s T a zónou UTC
```

Literál, který vypadá jako datum, ale platným datem není, třeba `2024-02-30`, se nepřevede a zůstane řetězcem.


Entity
------
Entita je struktura, která připomíná volání funkce:

```neon
Column(type: int, nulls: yes)
```

V PHP se naparsuje jako objekt [api:Nette\Neon\Entity]:

```php
// PHP
new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true])
```

Entity se mohou i zřetězit:

```neon
Column(type: int, nulls: yes) Field(id: 1)
```

Což se v PHP naparsuje tímto způsobem:

```php
// PHP
new Nette\Neon\Entity(Nette\Neon\Neon::Chain, [
	new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true]),
	new Nette\Neon\Entity('Field', ['id' => 1]),
])
```

Hodnota `Neon::Chain` je `!!chain`, takže toto jméno je vyhrazené a pro vlastní entitu ho použít nelze.

Uvnitř závorek platí pravidla pro inline zápis používaný u mapování a sekvencí, tedy může být klidně i víceřádkový a pak není nutné uvádět čárky:

```neon
Column(
	type: int
	nulls: yes
)
```


Komentáře
---------
Komentáře začínají znakem `#` a všechny následující znaky napravo jsou ignorovány:

```neon
# this line will be ignored by the interpreter
street: 742 Evergreen Terrace
city: Springfield  # this is ignored too
country: USA
```


Neon versus JSON
================
JSON je téměř podmnožinou NEONu, takže prakticky každý JSON se dá parsovat jako NEON. Jedinou výjimkou je dvojtečka na začátku řádku přilepená k hodnotě, třeba `"a"` a pod ním řádek s `:1`, což NEON čte jako řetězec `:1`:

```neon
{
"php": {
	"date.timezone": "Europe\/Prague",
	"zlib.output_compression": true
},
"database": {
	"driver": "mysql",
	"username": "root",
	"password": "beruska92"
},
"users": [
	"Dave", "Kryten", "Rimmer"
]
}
```

Co kdybychom vynechali uvozovky?

```neon
{
php: {
	date.timezone: Europe/Prague,
	zlib.output_compression: true
},
database: {
	driver: mysql,
	username: root,
	password: beruska92
},
users: [
	Dave, Kryten, Rimmer
]
}
```

A složené závorky a čárky?

```neon
php:
	date.timezone: Europe/Prague
	zlib.output_compression: true

database:
	driver: mysql
	username: root
	password: beruska92

users: [
	Dave, Kryten, Rimmer
]
```

Nejsou seznamy s odrážkami lépe čitelné?

```neon
php:
	date.timezone: Europe/Prague
	zlib.output_compression: true

database:
	driver: mysql
	username: root
	password: beruska92

users:
	- Dave
	- Kryten
	- Rimmer
```

Přidáme komentáře?

```neon
# my web application config

php:
	date.timezone: Europe/Prague
	zlib.output_compression: true  # use gzip

database:
	driver: mysql
	username: root
	password: beruska92

users:
	- Dave
	- Kryten
	- Rimmer
```

Hurá, teď znáte syntaxi NEONu!

{{maintitle: Formát NEON: lidsky čitelná alternativa k YAML a JSON}}
{{description: NEON je snadno čitelný formát pro serializaci dat, podobný YAMLu. Hlavní rozdíl je v tom, že podporuje entity a k odsazování můžete použít i tabulátory.}}

Formát NEON

NEON je lidsky čitelný strukturovaný datový formát. V Nette se používá pro konfigurační soubory. Také se používá pro strukturovaná data, jako jsou nastavení, jazykové překlady atd. Vyzkoušejte si jej.

NEON je zkratka pro Nette Object Notation. Je méně složitý a nemotorný než XML nebo JSON, ale poskytuje podobné funkce. Je velmi podobný YAML. Hlavní předností je to, že NEON má takzvané entity, díky kterým je konfigurace DI služeb taky sexy. A umožňuje odsazovat tabulátory.

NEON je postaven od základů tak, aby byl snadno použitelný. Knihovny pro PHP, JavaScript a Python, podporu v editorech a specifikaci formátu najdete na stránce Nástroje a knihovny.

Syntaxe

Soubor psaný v NEON obvykle představuje pole nebo mapování.

Mapování

Mapování je sada párů klíč-hodnota, v PHP by se řeklo asociativní pole. Každá dvojice je zapsána jako key: value, mezera za : je nutná. Hodnotou může být cokoliv: řetězec, číslo, boolean, null, sekvence nebo jiné mapování.

street: 742 Evergreen Terrace
city: Springfield
country: USA

V PHP by se stejná struktura zapsala jako:

[ // PHP
	'street' => '742 Evergreen Terrace',
	'city' => 'Springfield',
	'country' => 'USA',
]

Tento zápis se označuje jako blokový, protože všechny položky jsou na samostatném řádku a mají stejné odsazení (v tomto případě žádné). NEON podporuje také inline reprezentaci mapování, která je uzavřená do závorek, odsazení nehraje žádnou roli a oddělovačem jednotlivých prvků je buď čárka, nebo nový řádek:

{street: 742 Evergreen Terrace, city: Springfield, country: USA}

Totéž zapsané na více řádcích (na odsazení nezáleží):

{
	street: 742 Evergreen Terrace
		city: Springfield, country: USA
}

Místo : lze alternativně používat =, a to jak v blokovém, tak v inline zápisu:

{street=742 Evergreen Terrace, city=Springfield, country=USA}

Sekvence

Sekvence jsou v PHP indexované pole. Zapisují se jako řádky začínající spojovníkem - následovaným mezerou. Hodnotou opět může být cokoliv: řetězec, číslo, boolean, null, sekvence nebo jiné mapování.

- Cat
- Dog
- Goldfish

V PHP by se stejná struktura zapsala jako:

[ // PHP
	'Cat',
	'Dog',
	'Goldfish',
]

Tento zápis se označuje jako blokový, protože všechny položky jsou na samostatném řádku a mají stejné odsazení (v tomto případě žádné). NEON podporuje také inline reprezentaci sekvence, která je uzavřená do závorek, odsazení nehraje žádnou roli a oddělovačem jednotlivých prvků je buď čárka, nebo nový řádek:

[Cat, Dog, Goldfish]

Totéž zapsané na více řádcích (na odsazení nezáleží):

[
	Cat, Dog
		Goldfish
]

V inline reprezentaci nelze používat odsazující odrážky.

Kombinace

Hodnotami mapování a sekvencí mohou být jiné mapování a sekvence. Hlavní roli hraje úroveň odsazení. V následujícím příkladu má pomlčka použitá k označení položek sekvence větší odsazení než klíč pets, takže se položky stávají hodnotou prvního řádku:

pets:
   - Cat
   - Dog
cars:
   - Volvo
   - Skoda

V PHP by se stejná struktura zapsala jako:

[ // PHP
	'pets' => [
		'Cat',
		'Dog',
	],
	'cars' => [
		'Volvo',
		'Skoda',
	],
]

Lze kombinovat blokový a inline zápis:

pets: [Cat, Dog]
cars: [
	Volvo,
	Skoda,
]

Uvnitř inline zápisu již nelze používat zápis blokový, tohle nefunguje:

item: [
	pets:
	 - Cat     # TOHLE NELZE!!!
	 - Dog
]

V předchozím případě jsme zapsali mapování, jehož prvky byly sekvence, teď to zkusíme obráceně a vytvoříme sekvenci obsahující mapování:

-
	name: John
	age: 35
-
	name: Peter
	age: 28

Není nutné, aby odrážky byly na samostatných řádcích, lze je umístit i tímto způsobem:

- name: John
  age: 35
- name: Peter
  age: 28

Je na vás, jestli klíče zarovnáte do sloupce pomocí mezer nebo použijete tabulátor.

Protože v PHP se používá pro mapování i sekvence stejná struktura, tedy pole, lze obojí sloučit. Odsazení je tentokrát stejné:

- Cat
street: 742 Evergreen Terrace
- Goldfish

V PHP by se stejná struktura zapsala jako:

[ // PHP
	'Cat',
	'street' => '742 Evergreen Terrace',
	'Goldfish',
]

Položka bez klíče dostane celočíselný klíč o jedna větší než největší celočíselný klíč před ní, stejně jako v PHP. Takže {5: Cat, Dog} dá položce Dog klíč 6.

Řetězce

Řetězce v NEON lze uzavřít do jednoduchých i dvojitých uvozovek. Ale jak vidíte, mohou být také bez uvozovek.

- Řetězec v NEON bez uvozovek
- 'Řetězec v NEON v jednoduchých uvozovkách'
- "Řetězec v NEON ve dvojitých uvozovkách"

Pokud řetězec obsahuje znaky ` # " ' ` , : = - [ ] { } ( ) `, které lze zaměnit s NEON syntaxí, je potřeba jej uzavřít do uvozovek. Doporučujeme použít jednoduché uvozovky, protože v nich se nepoužívá escapování. Pokud potřebujete v takovém řetězci zapsat uvozovku, zdvojte ji:

'Uvozovka '' uvnitř řetězce v jednoduchých uvozovkách'

Dvojité uvozovky umožňují používat escape sekvence pro zápis speciálních znaků pomocí zpětných lomítek \. Podporovány jsou všechny escape sekvence jako u formátu JSON a navíc \_, což je nedělitelná mezera, tedy \u00A0.

- "\t \n \r \f \b \" \\ \/ \_"
- "\u00A9"

Existují další případy, kdy je potřeba uzavřít řetězce do uvozovek:

Víceřádkové řetězce

Víceřádkový řetězec začíná a končí trojitou uvozovkou na samostatných řádcích. Odsazení prvního neprázdného řádku se odstraní ze všech řádků:

'''
	první řádek
		druhý řádek
	třetí řádek
	'''

V PHP bychom totéž napsali jako:

"první řádek\n\tdruhý řádek\ntřetí řádek" // PHP

Řádek odsazený méně než první neprázdný řádek si své odsazení ponechá celé. Řádek jen z mezer nebo tabulátorů není prázdný, takže pokud je první, určí odsazení on.

Escapovací sekvence fungují jen u řetězců uvozených dvojitými uvozovkami místo apostrofů:

"""
	Copyright \u00A9
"""

Zpětné lomítko na konci řádku ho nespojí s dalším řádkem, v řetězci zůstane.

Čísla

NEON rozumí číslům zapsaným v tzv. vědecké notaci a také číslům v binární, osmičkové a hexadecimální soustavě:

- 12         # celé číslo
- 12.3       # float
- +1.2e-34   # exponenciální číslo

- 0b11010    # binární číslo
- 0o666      # osmičkové číslo
- 0x7A       # hexa číslo

Předpony 0b, 0o a 0x se píšou malými písmeny a bez znaménka, takže 0X10 a -0x1 jsou řetězce. Úvodní nuly neznamenají osmičkové číslo: 0777 je 777. Podtržítka mezi číslicemi povolená nejsou, 1_000 je řetězec.

Nulls

Null lze v NEON vyjádřit pomocí null nebo neuvedením hodnoty. Povoleny jsou také varianty s velkým prvním nebo velkými všemi písmeny.

a: null
b:

Booleans

Logické hodnoty jsou v NEON vyjádřeny pomocí true / false nebo yes / no. Povoleny jsou také varianty s velkým prvním nebo velkými všemi písmeny.

[true, TRUE, True, false, yes, no]

Slova on a off, která YAML 1.1 čte jako logické hodnoty, jsou v NEONu obyčejné řetězce.

Datum

NEON používá k vyjádření dat následující formáty a automaticky je převede na objekty DateTimeImmutable:

- 2016-06-03                  # datum
- 2016-06-03 19:00:00         # datum & čas
- 2016-06-03 19:00:00.1234    # datum & mikročas
- 2016-06-03 19:00:00 +0200   # datum & čas & zóna
- 2016-06-03 19:00:00 +02:00  # datum & čas & zóna
- 2016-06-03T19:00:00Z        # ISO 8601 s T a zónou UTC

Literál, který vypadá jako datum, ale platným datem není, třeba 2024-02-30, se nepřevede a zůstane řetězcem.

Entity

Entita je struktura, která připomíná volání funkce:

Column(type: int, nulls: yes)

V PHP se naparsuje jako objekt Nette\Neon\Entity:

// PHP
new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true])

Entity se mohou i zřetězit:

Column(type: int, nulls: yes) Field(id: 1)

Což se v PHP naparsuje tímto způsobem:

// PHP
new Nette\Neon\Entity(Nette\Neon\Neon::Chain, [
	new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true]),
	new Nette\Neon\Entity('Field', ['id' => 1]),
])

Hodnota Neon::Chain je !!chain, takže toto jméno je vyhrazené a pro vlastní entitu ho použít nelze.

Uvnitř závorek platí pravidla pro inline zápis používaný u mapování a sekvencí, tedy může být klidně i víceřádkový a pak není nutné uvádět čárky:

Column(
	type: int
	nulls: yes
)

Komentáře

Komentáře začínají znakem # a všechny následující znaky napravo jsou ignorovány:

# this line will be ignored by the interpreter
street: 742 Evergreen Terrace
city: Springfield  # this is ignored too
country: USA

Neon versus JSON

JSON je téměř podmnožinou NEONu, takže prakticky každý JSON se dá parsovat jako NEON. Jedinou výjimkou je dvojtečka na začátku řádku přilepená k hodnotě, třeba "a" a pod ním řádek s :1, což NEON čte jako řetězec :1:

{
"php": {
	"date.timezone": "Europe\/Prague",
	"zlib.output_compression": true
},
"database": {
	"driver": "mysql",
	"username": "root",
	"password": "beruska92"
},
"users": [
	"Dave", "Kryten", "Rimmer"
]
}

Co kdybychom vynechali uvozovky?

{
php: {
	date.timezone: Europe/Prague,
	zlib.output_compression: true
},
database: {
	driver: mysql,
	username: root,
	password: beruska92
},
users: [
	Dave, Kryten, Rimmer
]
}

A složené závorky a čárky?

php:
	date.timezone: Europe/Prague
	zlib.output_compression: true

database:
	driver: mysql
	username: root
	password: beruska92

users: [
	Dave, Kryten, Rimmer
]

Nejsou seznamy s odrážkami lépe čitelné?

php:
	date.timezone: Europe/Prague
	zlib.output_compression: true

database:
	driver: mysql
	username: root
	password: beruska92

users:
	- Dave
	- Kryten
	- Rimmer

Přidáme komentáře?

# my web application config

php:
	date.timezone: Europe/Prague
	zlib.output_compression: true  # use gzip

database:
	driver: mysql
	username: root
	password: beruska92

users:
	- Dave
	- Kryten
	- Rimmer

Hurá, teď znáte syntaxi NEONu!