Cílem je implementovat částečnou substituci pro Handlebars šablony.
Program dostanete jeden argument a to je cesta k souboru šablony. Pokud se soubor nepodaří otevřít, program vypíše Can not open file\n (\n je znak konce řádku) a skončí. Pokud není šablona validní, program vypíše Invalid template\n a skončí. Pokud se povede šablonu načíst program čte a vyhodnocuje příkazy ze standardního vstupu.
Handlebars formát
Handlebars je textový šablonovací formát. Kontrolní výrazy začínají znaky {{ a končí }}. Kontrolní sekvence může obsahovat jeden kontrolní výraz, nebo jejich dvojici. Ve druhém případě slouží první výraz jako otvírací a druhý jako zavírací. Mezi otevírací a zavírací výraz je možné vložit další obsah, čímž získáváme stromovou strukturu podobou třeba HTML.
Validní šablona musí:
obsahovat pouze kontrolní výrazy níže uvedené
být korektně "uzávorkovaná", otvírací a zavírací kontrolní výrazy se nesmí křížit
Názvy proměnných v kontrolních výrazech je třeba očistit o bílé znaky. Následující zápisy ekvivalentní:
<p>{{firstname}}</p> <p>{{ firstname}}</p> <p>{{ firstname }}</p> <p>{{ firstname }}</p>
Všechny výrazy reprezentují proměnnou s názvem firstname. Podobné pravidlo platí i pro výrazy obsahující klíčové slovo, například if.
Příklady:
{{#if firstname}} {{#if firstname}} {{#if firstname }}
Všechny výrazy využívají proměnnou jménem firstname.
Dále jsou popsány podporované kontrolní výrazy.
Proměnná
Příklad níže ukazuje použití kontrolního výrazy proměnné s názvem firstname.
<p>{{firstname}}</p>
Při dosazení proměnné, je celý kontrolní výraz nahrazen hodnotou proměnné. Například, pokud by proměnná firstname měla hodnotu Ailish získáme výraz:
<p>Ailish</p>
Klíčové slovo 'with'
Výraz má s with má jeden argument oddělený mezerou. Hodnota argumentu následovaná znakem tečky je použita jako prefix pro všechny proměnné v podstromu výrazu.
Příklad použití with:
{{#with person}}<p>{{firstname}}</p>{{/with}}
V tomto příklady je proměnná firstname přístupná pod jménem person.firstname. Předpona person. je utvořena z argumentu od with a znaku tečky**.**
Klíčové slovo 'if'
Klíčové slovo if značí oblast podmíněného výstupu. Výraz má jeden argument a to je jméno proměnné.
Příklad níže dá na výstup inner content pouze tehdy, pokud existuje neprázdná proměnná firstname.
{{#if firstname}}inner content{{/if}}
Stejně jako pro proměnné i pro if je použitý prefix of with. Příklad níže tedy tedy využívá proměnné person.firstname.
{{#with person}}<p>{{#if firstname}}inner content{{/if}}</p>{{/with}}
Klíčové slovo 'each'
Klíčové slovo each označuje kolekci hodnot. Výraz má jeden jeden argument a to je jméno proměnné.
<ul> {{#each people}} <li>{{firstname}}</li> {{/each}} </ul>
Hodnoty v podstromu výrazy jsou dostupné pomocí předpony .. V příklady výše bych mohli adresovat vnitřní proměnnou firstname pomocí zápisu **people..firstname**.
Příkazy
Příkazy jsou zadávány na standardní vstup. Jednotlivé příkazy jsou odděleny znakem konce řádku (\n). Prázdné řádky by měl program ignorovat. Znak konce řádku není součástí příkazu. Pokud je příkaz nevalidní, nebo neznámý program musí vypsat Invalid command\n a pokračovat načtením dalšího příkazu. Program skončí ve chvíli, kdy není již co číst - tedy narazí na konec standardního vstupu.
Níže jsou popsány podporované příkazy.
Příkaz nebere žádný argument. Vykonáním příkazy je vytisknutí aktuálního stavu šablony na standardní výstup. Bílé znaky mimo kontrolní výrazu musí být zachovány. Pokud kontrolní výraz má argumenty, jsou ty odděleny jednou mezerou. Vstupy ze sekce Handlebars formát by tak byly vypsány následovně:
{{firstname}} {{#if firstname}}
set
Tento příkaz bere dva argumenty:
jméno proměnné
hodnotu proměnné Pokud jsou oba argumenty přítomné, jsou oddělené bílým znakem (mezeru). To znamená, že jméno proměnné nemůže obsahovat bílý znak (mezeru). Zápis příkazy tedy odpovídá následující šabloně:
set {name-without-space} {rest of line is a value}
Příklady:
set name Ailish
proměnné name s hodnotou Ailish
set person.message Secret message ...
proměnná person.message s hodnotou Secret message ...
set empty
proměnná empty s hodnotou `` (prázdný řetězec)
set empty
proměnná empty s hodnotou `` (prázdný řetězec)(všimněte si mezery za empty)
set name Ailish
v tomto případě jsou dvě mezery po set, jméno proměnné je tedy `` (prázdný řetězec) hodnota je name Ailish
Jakmile program dostane proměnou a její hodnotu, musí provést nahrazení v šabloně. Každá proměnná stejného jména musí být nahrazena dodanou hodnotou. Nezapomínejte na prefixy dodané pomocí with a each.
Každá podmínka (if) obsahující danou proměnnou musí být vyhodnocena. Pokud je hodnota prázdná, je kontrolní sekvence if včetně obsahu z šablony odevzdána. Pokud je hodnota neprázdná, je kontrolní sekvence if nahrazena svým obsahem.
Příklady
Takto sekce obsahuje příklady šablon, příkazů a výstupů
Jednoduché nahrazení
Template:
Message: {{message}}
Commands (starting with '>' (not part of the input) and output):
> set message You can do this > print Message: You can do this
Nahrazení na více místech
Template:
{{value}} + {{value}} = {{result}}
Commands (starting with '>' (not part of the input) and output):
> set value 1 > set result 2 > print 1 + 1 = 2
Klíčové slovo with
Template:
{{value}} {{#with content}} {{value}} {{/with}}
Commands (starting with '>' (not part of the input) and output):
> set value one > print one {{#with content}} {{value}} {{/with}} > set content.value two > print one {{#with content}} two {{/with}}
Podmíněný výstup I
|{{#if should_render}} RENDER {{/if}}|
Commands (starting with '>' (not part of the input) and output):
> set should_render one > print | RENDER |
Podmíněný výstup II
|{{#if should_render}} RENDER {{/if}}|
Commands (starting with '>' (not part of the input) and output):
> set should_render > print ||
Nahrazování v kolekcích
Messages: {{#each items}} {{value}} {{unchanged}} {{/each}}
Commands (starting with '>' (not part of the input) and output):
> set items.*.value Single value ... > print Messages: {{#each items}} Single value ... {{unchanged}} {{/each}}