Skip to content

Referencia: Gramatika, chyby a hraničné prípady

Úvod · Index funkcií · Ťahák

Identifikátory, úrovne zhody a pravidlá verziovania na tejto stránke sú stable — zmrazené s vydaním 1.0, pretože implementátor sa na ne musí vedieť spoľahnúť. Knižnica vstavaných funkcií a úrovne rozšírení sú experimental. Každá sekcia nesie vlastnú značku.


28. Formát súboru a balenie

Samostatné súbory: .rea

stableod 1.0UTF-8 plain text, no metadata

Súbor príbehu je čistý text a neobsahuje vôbec žiadne metadáta — práve toto oddelenie udržuje .rea čitateľné v ľubovoľnom editore a je zmrazené.

Súbor .rea je textový súbor v kódovaní UTF-8, ktorý obsahuje prózu a syntax jedného príbehu. Nenesie žiadne vlastné metadáta — tie všetky žijú v manifeste balíka.

Balíky: .reast

experimentalod 1.0ZIP: manifest.json + story/ + assets/

Obe štruktúry — zabalená (s manifestom) aj plochá (jediný vstupný súbor, bez metadát) — sa dnes načítajú.

Súbor .reast je ZIP archív (podobne ako EPUB), ktorý zväzuje jednu alebo viac častí s ich médiami a metadátami, buď v štruktúre riadenej manifestom, alebo v plochej štruktúre. Štruktúru archívu na disku, celú schému manifest.json, import z GitHub repozitára, panel kariet čitačky, nastavenia relácie (reast.json), postupné načítavanie, rozdielové aktualizácie, podpisovanie balíkov, minifikáciu aj stav čítania viacdielnych príbehov popisuje v plnom rozsahu referencia formátu balíka .reast v dokumentácii jadra — táto sekcia pokrýva len pravidlá na úrovni jazyka, ktoré z tohto formátu vyplývajú.

Pravidlá na úrovni jazyka špecifické pre moduly rozšírení .rext (ktoré konštrukcie sú vnútri nich prípustné a prečo je na ich naviazanie potrebný {use}) nájdete v časti Kde sa pravidlá líšia v súboroch .rext.

29. Identifikátory a pomenovanie

stableod 1.0domain.name, any Unicode except space and dot

Zmrazené preto, aby neanglicky píšuci autor mohol pomenovať stav vo vlastnej abecede a mať istotu, že to bude fungovať aj naďalej.

Konvencie pomenovania

PrvokKonvenciaPríklad
Premennédomena.nazovstory.player.gold, story.quest.has_key
Funkciesnake_casecalculate_damage, greet
Kotvysnake_case#the_clearing
Príkazysnake_case{voice}, {wait}
Identifikátory karietsnake_case[@dark_elf], [$magic_ring]
Kľúče metadátsnake_casetitle, draft_date

Pravidlá pomenovania premenných

Všetky trvalé premenné (v rozsahu príbehu aj globálne) musia mať aspoň jeden prefix domény oddelený bodkou .:

rea
{set story.player.gold = 100}
{set story.quest.has_key = true}
{set story.tool.knife = "rusty"}
{set story.role.king.power = 9}

Prefixy domén organizujú premenné do logických menných priestorov, vďaka ktorým je stav príbehu sám o sebe zrozumiteľný. Názvy domén si autori volia voľne — bežné vzory zahŕňajú mená postáv, kategórie objektov alebo pojmy príbehu.

Výnimka z požiadavky domény: premenné v rozsahu nadpisu (jednoduchý názov bez bodky), premenné cyklov ({for}) a parametre funkcií — tie používajú jednoduché názvy bez bodiek.

Pravidlá identifikátorov

Každý úsek bodkovanej cesty (doména alebo názov) sa riadi týmito pravidlami:

  • Môže obsahovať ľubovoľný znak Unicode okrem medzery () a bodky (.)
  • Musí obsahovať aspoň jeden nečíselný znak (na odlíšenie od čísel)
  • Rozlišuje veľkosť písmen

To znamená, že neanglicky píšuci autori môžu voľne používať vlastnú abecedu:

rea
{set hráč.zlato = 100}
{set 道具.剣 = "katana"}
{set игрок.здоровье = 80}

Jednoduché identifikátory (funkcie, príkazy, kotvy, identifikátory kariet) sa riadia rovnakými pravidlami znakov, ale bodku nevyžadujú.


30. Vstavané funkcie

Funkcie pre reťazce

FunkciaPopis
length(str)Počet znakov
upper(str)Prevod na veľké písmená
lower(str)Prevod na malé písmená
trim(str)Odstránenie medzier na začiatku a konci
contains(str, sub)Overí, či obsahuje podreťazec
replace(str, old, new)Nahradí výskyty
split(str, delimiter)Rozdelí na pole
join(array, delimiter)Spojí pole do reťazca

Matematické funkcie

FunkciaPopis
abs(n)Absolútna hodnota
min(a, b)Menšia z dvoch hodnôt
max(a, b)Väčšia z dvoch hodnôt
round(n)Zaokrúhlenie na najbližšie celé číslo
floor(n)Zaokrúhlenie nadol
ceil(n)Zaokrúhlenie nahor
random(min, max)Náhodné celé číslo v rozsahu (vrátane hraníc)
clamp(value, min, max)Obmedzí hodnotu na rozsah

Funkcie pre polia

FunkciaPopis
length(arr)Počet prvkov
append(arr, item)Pridá na koniec
remove(arr, item)Odstráni prvý výskyt
contains(arr, item)Overí, či obsahuje položku
shuffle(arr)Náhodne premieša poradie
sort(arr)Zoradí vzostupne
slice(arr, start, end)Vyberie podpole

Geografické funkcie

Body sa zapisujú literálom @(lat, lng) (pozri Literály súradníc); všetko, čo má rozlohu, z bodov vytvára jedna z týchto funkcií. Každý polomer je v metroch.

FunkciaPopis
path(p1, p2, ...)Usporiadaná reťaz aspoň dvoch bodov; bez vnútra
area(p1, p2, p3, ...)Uzavretý prstenec aspoň troch bodov; prstenec sa uzatvára sám
circle(stred, metre)Všetko do vzdialenosti metre od bodu
buffer(tvar, metre)Všetko do vzdialenosti metre od trasy, oblasti, kruhu alebo bodu
distance(a, b)Vzdialenosť dvoch bodov po veľkej kružnici, v metroch
bearing(a, b)Smer z a do b, v stupňoch od severu

Zmena kolekcií

Polia podporujú volania v štýle metód:

rea
{set story.player.inventory = ["sword", "shield"]}
{append(story.player.inventory, "potion")}
{remove(story.player.inventory, "shield")}

Dopytovacie funkcie

FunkciaPopis
visited(anchor)Navštívil už čitateľ túto kotvu?
visit_count(anchor)Koľkokrát ju navštívil
turns()Celkový počet interakcií čitateľa doteraz
elapsed()Čas od začiatku príbehu (v sekundách)
choice_count()Počet dostupných volieb v aktuálnom bode
reader_count()Počet aktívnych čitateľov (kooperatívne čítanie)

Funkcie náhodnosti a kociek

FunkciaPopis
dice(notation)Hod kockou štandardným zápisom (napr. "2d6+3"). Pozri Sekciu 21

Náhodnosť je seedovaná a čítanie sa dá zopakovať. random(), shuffle() a všetko, čo je na nich postavené (vrátane std/dice), čerpá z generátora, ktorý vlastní runtime, nie z globálneho zdroja náhodnosti hostiteľa. Príbeh si pri spustení vytiahne jeden seed; stav čítania nesie tento seed aj aktuálnu pozíciu generátora, takže obnovenie uloženia pokračuje identickou postupnosťou a krok späť zreprodukuje hody, ktoré po ňom nasledovali. Reštart príbehu vytiahne nový seed — opätovné prečítanie je skutočne novým prechodom.

experimentalod 1.0random() · shuffle() · std/dice

Každé ťahanie pochádza z generátora, ktorý vlastní runtime a nesie ho súbor uloženia, takže obnovenie uloženia pokračuje identickou postupnosťou. Testovacia funkcia seed(n) nie je implementovaná — seed namiesto toho pripnite cez voľbu jadra u hostiteľa.

Funkcie zariadenia a sveta

FunkciaPopis
has(feature)Overí schopnosť zariadenia (napr. "camera", "gps", "nfc")

Konštruktory typov a konverzné funkcie

FunkciaPopis
number(x)Prevod na číslo. number("42")42, number("abc")undefined
string(x)Prevod na reťazec. string(42)"42", string(true)"true"
boolean(x)Prevod na logickú hodnotu. Nepravdivé hodnoty → false, ostatné → true
integer(x)Prevod na celé číslo (oreže). integer(3.7)3
datetime("ISO-8601-string")Vytvorí datetime z reťazca ISO 8601 (podporuje zástupné *)
duration("ISO-8601-duration")Vytvorí trvanie z reťazca trvania ISO 8601

Geografický bod má literálovú syntax — @(lat, lng), najprv zemepisná šírka (pozri Sekciu 11) — pretože príbeh zasadený do reálneho miesta ich píše veľmi veľa. Všetko, čo má rozlohu, je bežné volanie nad bodmi: circle(p, metre), area(p1, p2, p3, ...), path(p1, p2, ...), buffer(tvar, metre). distance(a, b) a bearing(a, b) merajú medzeru medzi dvoma bodmi — v metroch a v stupňoch od severu. within(bod, oblasť) je funkcionálna podoba bod matches oblasť a within(bod, "nazov_zastavky") opätovne použije vlastnú oblasť pomenovanej zastávky namiesto toho, aby autor prepísal jej súradnice.

Funkcie variácie textu a lokalizácie

FunkciaPopis
select(value, he="x", she="y", other="z")Vráti text zodpovedajúci hodnote (záloha cez other)
plural(count, one="y", other="z", ...)Skloňovanie podľa CLDR; kategória z Intl.PluralRules pre lokál hostiteľa
ordinal(n) / ordinal(n, one=..., ...)Radová číslovka; anglická prípona len pre lokály en*, inak číslo naformátované podľa lokálu (pozri nižšie)
formatNumber(value, locale?, style=..., ...)Formátovanie čísel podľa lokálu (pozri Sekciu 22)
calendar(date, month=..., weekday=..., era=...)Mapovanie fantasy kalendára (pozri Sekciu 22)

Kategórie množného čísla a radových čísloviek sa rozlišujú z CLDR cez Intl.PluralRules, riadené lokálom dodaným hostiteľom — nie tabuľkou pre jednotlivé jazyky zapečenou v jadre. calendar() je jediná funkcia tu, ktorá je stále vo vývoji; pozri index funkcií.

Funkcie dátumu a času

experimentalod 1.0{formatDate(value, "long")} · {dateDiff(a, b, "d")}

Hodiny, lokál a časové pásmo dodáva hostiteľ, formátovanie ide cez Intl.DateTimeFormat; celým rozhraním je enum style, bez reťazcov s tokenmi pre autora.

Vstavané funkcie dátumu a času pracujú s reťazcami ISO 8601 a časovými značkami v milisekundách. Hodiny, lokál a časové pásmo dodáva hostiteľ; formátovanie deleguje na Intl.DateTimeFormat (údaje CLDR). Neplatný vstup vráti '' alebo 0.

FunkciaPopis
now()Aktuálna časová značka v milisekundách (hodiny hostiteľa)
today()Aktuálny kalendárny dátum ako YYYY-MM-DD v časovom pásme hostiteľa
formatDate(value, style?)Naformátuje dátum; style ∈ iso | short | medium | long | full (predvolene medium)
formatTime(value, style?)Naformátuje dennú dobu rovnakými štýlmi
formatDateTime(value, style?)Naformátuje dátum aj čas spolu rovnakými štýlmi
parseDate(value)Rozparsuje reťazec dátumu na časovú značku v milisekundách (0, ak je neplatný)
dateDiff(a, b, unit?)Rozdiel a − b; unit ∈ ms | s | m | h | d (predvolene ms)
dayOfWeek(value)Deň v týždni v časovom pásme hostiteľa (0 = nedeľa, 6 = sobota)
dateAdd(value, amount, unit?)Pripočíta trvanie (unit ∈ ms | s | m | h | d | M | y); vráti reťazec ISO
duration(value)Trvanie ISO 8601 v milisekundách — duration("PT30M") je 1800000
between(time, from, to)Je denný čas vnútri rozsahu; rozsah cez polnoc je bežný prípad
elapsed(value)Milisekundy od okamihu, podľa hodin hostiteľa

Štýl iso dáva YYYY-MM-DD (dátum), HH:mm:ss (čas) alebo úplný reťazec ISO 8601 (dátum a čas). Neexistuje formátovací reťazec s tokenmi dátumu (YYYY-MM-DD) dostupný autorovi — celým rozhraním je enum style.

select() umožňuje variáciu zámen a rodu bez vetvenia:

rea
{set char.pronoun = "she"}
{select(char.pronoun, he="Vytasí svoj meč", she="Vytasí svoj meč", other="Vytasia svoj meč")}

plural() sa riadi pravidlami množného čísla CLDR pre lokál dodaný hostiteľom:

rea
Našiel si {plural(gem_count, one="drahokam", few="{} drahokamy", other="{} drahokamov")}.

Podrobné použitie všetkých lokalizačných funkcií nájdete v Sekcii 22.

Testovacie funkcie

FunkciaPopis
seed(n)Nastaví seed náhodnosti pre deterministické miešanie a random()
snapshot()Zachytí aktuálny stav na porovnanie
rea
{seed(42)}
Minca padla na {~hlavu|znak}.

Pri rovnakom seede je každý náhodný výsledok reprodukovateľný — nevyhnutné pri testovaní a ladení príbehov.

Stav príkazu

Pomenované príkazy sprístupňujú stav:

rea
{if rich_check.executed.count > 0 begin}
  Už ťa raz preverovali, či si bohatý.
{end if}

{rich_check.executed.last_time}

31. Rozšíriteľnosť

experimentalod 1.0{use "extensions/inventory" as inv}

Moduly obsahujúce len deklarácie, ktoré cestujú vnútri balíka a sú skompilované a overené ešte pred spustením akejkoľvek prózy.

Rea sa rozširuje v dvoch úrovniach. Úroveň 1 — rozšírenia Rea je prenosný, izolovaný kód Rea, ktorý cestuje vnútri balíka (súbory .rext), plus vyhradená štandardná knižnica std/* dodávaná so samotným jazykom. Úroveň 2 — rozšírenia hostiteľa je JavaScript dodaný vkladajúcou aplikáciou; stoja mimo samotného jazyka Rea a dosiahnuteľné sú len vtedy, keď ich vkladateľ poskytne.

Úroveň 1 — rozšírenia Rea (priestor autora, prenosné, izolované)

experimentalod 1.0declaration-only Rea

Len funkcie, konštanty najvyššej úrovne, {use} a komentáre — akýkoľvek uzol prózy kdekoľvek v súbore je chybou načítania.

Rozšírenie Rea je súbor .rext (pozri Kde sa pravidlá líšia v súboroch .rext) obsahujúci výhradne deklarácie: bloky {function}{end function}, konštanty {set} najvyššej úrovne, {use} a komentáre. Akýkoľvek uzol prózy — odsek, nadpis, skupina volieb, médium, citácia, dialóg či definícia karty — kdekoľvek v .rext je chybou načítania. Práve toto obmedzenie robí rozšírenie preskúmateľným okom aj strojovo kontrolovateľným.

Hodnoty {set} najvyššej úrovne sú súkromné konštanty modulu. Jeho funkcie ich čítajú, ale nie sú to premenné príbehu: nikdy sa neobjavia v exportovanom stave čítania, dva moduly môžu deklarovať konštantu s rovnakým názvom bez kolízie a modul nikdy nemôže prepísať premennú deklarovanú autorom. Parameter funkcie s rovnakým názvom konštantu zatieni. {set} vnútri tela funkcie sa riadi bežným rozsahom funkcií v Rea a premennú príbehu zapisuje — stav cyklu preto hromaďte rekurziou, nie počítadlom.

Rozšírenie naimportujete pomocou {use} a dáte mu alias; zapísaná cesta príponu .rext vynecháva. Exportované funkcie potom voláte cez alias:

rea
{use "extensions/inventory" as inv}

Tvoj batoh váži {inv.total_weight()} kg.

Pravidlá:

  • Rozlišovanie výhradne v rámci balíka — cesta {use} sa rozlišuje vnútri balíka, nikdy nie v súborovom systéme ani v sieti.
  • Graf {use} musí byť acyklický — cyklus načítanie zhodí a cyklus pomenuje.
  • Duplicitné názvy exportov sú chyba, nie „vyhráva prvý".
  • {use} na chýbajúcu cestu zhodí načítanie (rovnako ako položka manifest.extensions, ktorá v archíve nie je).

Súbory príbehu (.rea) môžu naďalej deklarovať {function}, ale tie sú súkromné a v rozsahu dokumentu — exportujú len súbory rozšírení. Ak chcete funkciu zdieľať medzi časťami, vložte ju do .rext a použite {use}.

std/* — štandardná knižnica

experimentalod 1.0{use "std/dice" as dice}

Rozlišuje sa priamo v jadre, nie v archíve ani u hostiteľa, takže funguje offline v ľubovoľnom vložení; std/dice je prvý modul.

std/* je vyhradený menný priestor rozlišovaný priamo v jadre, nie z archívu a nie od hostiteľa. {use "std/dice" as dice} preto funguje na ľubovoľnom hostiteľovi, offline a bez akejkoľvek podpory vkladateľa — dodáva sa s jazykom, namiesto toho, aby ho vkladala platforma. (Keby ho vkladala platforma, príbeh by sa vykreslil na rea.st a rozbil sa v cudzom vložení, čím by prišiel o prenosnosť, kvôli ktorej systém rozšírení existuje.) Archívny .rext, ktorý sa rozlišuje pod std/, je chyba načítania, a rozšírenie hostiteľa deklarujúce menný priestor std sa takisto odmietne.

std/dice exportuje:

FunkciaPopis
d(sides)Hodí jednou kockou s daným počtom stien
roll(count, sides)Súčet count kociek s sides stenami (obmedzené hĺbkou volaní)
advantage(sides)Hodí dvoma kockami a ponechá vyšší výsledok
disadvantage(sides)Hodí dvoma kockami a ponechá nižší výsledok
rea
{use "std/dice" as dice}

Zaženieš sa divoko a spôsobíš {dice.roll(2, 6)} poškodenia.

Úroveň 2 — rozšírenia hostiteľa (JavaScript dodaný vkladateľom)

experimentalod 1.0{ns.command args} · {ns.fn()}

JavaScript, ktorý vkladajúca aplikácia registruje pre každú inštanciu prehrávača; stojí mimo samotného jazyka Rea a príbeh musí deklarovať menné priestory, ktoré potrebuje.

Rozšírenia hostiteľa sú JavaScript registrovaný vkladateľom pre každú inštanciu prehrávača (pre každý prvok jadra), nikdy nie globálne. Dvaja prehrávači na jednej stránke môžu držať rôzne rozšírenia hostiteľa. Prispievajú:

  • Funkciami volateľnými z výrazov Rea ako {ns.fn()}.
  • Obsluhami príkazov pre príkazy s menným priestorom {ns.command args}. Príkaz vyžaduje argumenty: holé {ns.name} bez argumentov je bodkovaný odkaz na premennú, nie príkaz.
  • Vykresľovačmi uzlov, ktoré nahrádzajú vstavané vykreslenie daného typu uzla.

Tvrdé pravidlo: rozšírenie hostiteľa, ktoré potrebuje rozhranie zariadenia, vyšle udalosť na zbernicu, presne ako to robí vstavaný senzorový príkaz; kód jadra nikdy nevolá rozhranie zariadenia v mene rozšírenia.

Rozšírenia hostiteľa stoja mimo samotného jazyka Rea a dosiahnuteľné sú len vtedy, keď ich vkladateľ poskytne. Príbeh deklaruje menné priestory hostiteľa, ktoré potrebuje, cez manifest.requires; vkladateľ, ktorý požadovaný menný priestor nezaregistroval, príbeh radšej odmietne načítať, než by mal zlyhať uprostred kapitoly.

Vlastné typy kariet

draft{define card_type location, prefix="📍"}

Nové prefixy v hranatých zátvorkách nad rámec @, $ a &. Špecifikované ako budúci bod rozšírenia; vlastné *sady* kariet dnes pokrývajú väčšinu potreby, takže implementácia sa nezačala.

Vlastné sady kariet ({define cardset …}) sú vydané a pokrývajú väčšinu toho, po čom autori siahajú — pozri Sekciu 17. Nad ich rámec môžu rozšírenia v budúcnosti definovať nové typy kariet s vlastným prefixom v hranatých zátvorkách, nad rámec vstavaných @, $ a &:

rea
{define card_type location, prefix="📍", name="Miesto", fields="name, description, image, coordinates"}

{define location tavern name="Hrdzavá kotva", description="Slabo osvetlená krčma neďaleko prístavu.", image="assets/tavern.webp", coordinates="@(48.1486, 17.1077)"}

Prichádzaš do [📍tavern].

Šifrovanie kódu rozšírení

Kód rozšírenia sa nikdy nešifruje. Zavádzač zašifrovaný .rext odmietne. Šifrovanie je ochrana obsahu, nie bezpečnostná hranica — sandbox rozšírenie obmedzuje rovnako, či je jeho zdroj zašifrovaný alebo nie — takže jeho zákaz nič obranné nestojí a prináša tri veci:

  1. Overenie skôr, než sa spustí próza. Odomykací kód môže doraziť uprostred príbehu; kód, ktorý sa objaví, až keď je čitateľ zaviazaný, by zlyhal v najhoršej možnej chvíli. Rozšírenia v čistom texte sa pri načítaní skompilujú a skontrolujú.
  2. Auditovateľnosť bez kľúča — nástrojom reast validate, editorom aj moderáciou platformy.
  3. Spustiteľnosť treťou vkladajúcou aplikáciou, ktorá kľúč nemá.

Ak chcete udržať tajomstvo mimo rozšírenia a zároveň ho overovať, nechajte funkciu všeobecnú a v čistom texte a tajomstvo vložte cez {set} do zašifrovanej kapitoly .rea, potom overujte proti tejto premennej namiesto jeho zapečenia:

rea
{comment extensions/gate.rext — čistý text, všeobecný, neobsahuje tajomstvo}
{function unlocked(given, expected) begin}
  {return given = expected}
{end function}
rea
{comment zašifrovaná kapitola .rea nesie tajomstvo}
{set crypt.passphrase = "moonlit-antler"}

{input name=attempt, placeholder="Vyslov to slovo"}
{if unlocked(attempt, crypt.passphrase) begin}
  Brána sa otvorí.
{end if}

Výhrada, povedaná otvorene: zašifrovaná .rea nie je tajomstvom pred odhodlaným čitateľom. Kľúč sa na zariadenie čitateľa dostane preto, aby sa kapitola vykreslila, takže crypt.passphrase sa dá vytiahnuť. Šifrovanie chráni pred prezradením zápletky, letmým nahliadnutím a prehľadaním archívu — nie pred motivovaným útočníkom. Čokoľvek, čo musí byť skutočne nefalšovateľné (odpoveď v súťaži, platené odomknutie), sa musí overiť na strane servera, a to je práca platformy, nie jadra (pozri aj Ochranu obsahu).

Obmedzenia sandboxu

Rozšírenia Rea bežia v tom istom izolovanom prostredí ako bežný kód Rea:

  • Žiadny prístup k súborovému systému nad rámec balíka
  • Žiadne sieťové požiadavky (len deklarované rozhrania platformy)
  • Žiadne spúšťanie ľubovoľného kódu — príbeh nemôže vložiť JavaScript, Python ani iný jazyk; rozšírenie Rea je izolovaná Rea a rozšírenie hostiteľa je vlastný kód vkladateľa, ktorý príbeh nikdy nevkladá
  • Limity pamäte a výpočtu presadzované runtimom — napríklad hĺbka rekurzie obmedzuje roll z std/dice na 64 kociek
  • Kód rozšírenia sa nikdy nešifruje (pozri vyššie), takže zostáva auditovateľný

Úrovne zhody

stableod 1.0Core · Standard · Platform

Tri deklarované úrovne, aby implementátor mohol čestne vydať čiastočné jadro; zmrazené, pretože celý zmysel je v tom, že označenie znamená všade to isté.

Rea definuje tri úrovne zhody, aby implementátori mohli stavať čiastočné implementácie bez toho, aby si nárokovali plný súlad so špecifikáciou. Každá úroveň stavia na predchádzajúcej:

ÚroveňSekciePopis
Core1 – 7, 9 – 14, 16, 25 – 26, 28 – 29Minimálna životaschopná interaktívna fikcia: text, formátovanie, nadpisy, odkazy, kotvy, príkazy, premenné, výrazy, riadenie toku, funkcie, voľby, únikové sekvencie, komentáre, formát súboru, identifikátory. Stačí na písanie vetviacich sa príbehov so stavom.
StandardCore + 8, 15, 17 – 19, 22 – 24, 27, 30 – 31, 32Plný zážitok pre jedného čitateľa: médiá, udalosti, karty, hlas, vstup a interakcia, skloňovanie, zámok, popisky, spracovanie chýb, vstavané funkcie, rozšíriteľnosť, prístupnosť.
PlatformStandard + 20 – 21Funkcie pre viacerých čitateľov a reálny svet: kooperatívne čítanie (parallel, vote, whisper, broadcast, race, exclusive, synchronize), interakcie s reálnym svetom (GPS, NFC, QR, fotoaparát, senzory). Vyžaduje sieťovú infraštruktúru a rozhrania zariadení.

Implementácia MUSÍ deklarovať, ktorú úroveň zhody podporuje. Keď príbeh použije funkcie nad úrovňou implementácie, funkcia neurobí nič a čitateľ na jej mieste nevidí nič — čo sa dozvie autor, popisuje Záznamy a úrovne zhody.

Implementácia Core stačí na textovú interaktívnu fikciu s voľbami a premennými — konkurencieschopná s Ink alebo ChoiceScript. Implementácia Standard zodpovedá plnému zážitku Reast pre jedného čitateľa. Implementácia Platform vyžaduje serverovú infraštruktúru na synchronizáciu medzi čitateľmi a rozhrania zariadení na interakciu s reálnym svetom.

Verziovanie špecifikácie

stableod 1.0manifest `rea: "1.0"`

Verziovanie MAJOR.MINOR s pravidlami doprednej kompatibility, ktoré parser musí dodržať. Zmrazené s vydaním 1.0.

Rea sa riadi schémou verzií MAJOR.MINOR (inšpirovanou YAML):

  • MAJOR — nekompatibilné zmeny, ktoré môžu znehodnotiť existujúce príbehy
  • MINOR — spätne kompatibilné doplnenia (nové príkazy, atribúty, funkcie)

1.0 je prvé vydanie jazyka. Všetko, čo je pod ním zverejnené, je autorom dostupné už teraz, na tej úrovni zrelosti, akú deklaruje jeho značka.

Príbeh Rea deklaruje, na ktorú verziu špecifikácie mieri, pomocou poľa rea v manifest.json:

json
{
  "rea": "1.0",
  "title": "Posledný lampáš",
  "author": [{ "name": "Elena Vossová" }],
  "version": "2.1"
}

Tu "rea": "1.0" znamená „tento príbeh používa verziu špecifikácie Rea 1.0", kým "version": "2.1" znamená „toto je verzia 2.1 samotného príbehu".

Ak kľúč rea chýba, platforma predpokladá najnovšiu podporovanú verziu. Parsery MUSIA odmietnuť príbehy mieriace na vyššiu verziu MAJOR, než akú podporujú. Parsery BY MALI prijať príbehy mieriace na nižšiu verziu MINOR v rámci tej istej verzie MAJOR a neznáme funkcie elegantne ignorovať.

Stabilita funkcií

Každá funkcia v tejto špecifikácii nesie pod vlastným nadpisom výslovnú značku stavu a celá množina je uvedená v indexe funkcií. Stavov je päť:

StavDostupné dnes?Význam
stableÁnoZmrazené. Zmeniť sa môže len v novej verzii MAJOR. Patrí sem prozaické jadro jazyka.
experimentalÁnoVydané a použiteľné, ale v rámci tejto verzie MAJOR sa ešte môže upraviť. Väčšina Rea je dnes na tejto úrovni.
developmentNieNavrhnuté a práve sa stavia. Zdokumentovaná syntax je taká, aká bude, ale jadro ju zatiaľ neprijíma.
draftNieŠpecifikované a prediskutované, aby bol tvar myšlienky zaznamenaný. Implementácia sa nezačala; návrh sa ešte môže úplne zmeniť.
cancelledNikdyZvážené a zámerne vylúčené. Zaznamenané preto, aby rozhodnutie zostalo viditeľné a neriešilo sa znovu.

Značka verzie sprevádza stav len pri funkciách stable a experimental — pri tých dvoch, ktoré sú skutočne zverejnené — a pomenúva verziu špecifikácie, v ktorej sa funkcia stala dostupnou. Funkcia development alebo draft verziu zatiaľ nemá a cancelled ju mať nikdy nebude.

Implementácia MÔŽE vydať ľubovoľnú podmnožinu funkcií development a draft; NESMIE si na ich základe nárokovať úroveň zhody, pretože príbeh sa nemôže spoliehať na niečo, čo žiadna iná implementácia nemá. Funkcie pridané po 1.0 nesú v tej istej značke svoju verziu zavedenia (since 1.1), takže autor vždy vie, ktorú verziu špecifikácie príbeh vyžaduje.

Stav nie je sľubom o termíne. development hovorí, že práca beží, draft hovorí, že myšlienka je zapísaná a nič viac — ani jedno nenaznačuje, kedy a či to dorazí.

Postup pri zastarávaní

Keď sa funkcia označí za zastaranú:

  1. Špecifikácia ju označí textom „(Zastarané od X.Y)" a zdokumentuje náhradu
  2. Parsery MUSIA zastarané funkcie podporovať aspoň jednu verziu MAJOR
  3. Parsery BY MALI pri použití zastaranej funkcie vydať varovanie
  4. Zastaraná funkcia sa odstráni v nasledujúcej verzii MAJOR (alebo neskôr)

Spätná kompatibilita

Parsery zhodné s Rea MAJOR.MINOR MUSIA:

  1. Prijať každý platný príbeh napísaný pre MAJOR.0 až MAJOR.MINOR
  2. Ignorovať neznáme kľúče metadát (už špecifikované v Sekcii 1)
  3. Preskočiť neznámy príkaz celý — aj s jeho blokom — bez varovania viditeľného pre čitateľa — a zaznamenať parse/unknown-command na autorskom kanáli
  4. Považovať neznáme inline formátovanie za doslovný text

Pravidlo 3 predtým znelo „zobraziť varovanie a blok príkazu preskočiť". Kde sa varovanie zobrazí, je práve otázka, na ktorú odpovedá dvojkanálový model zo Spracovanie chýb: čitateľovi nikdy, autorovi vždy, ako záznam. Čitateľ vidí preskočený blok a nič viac.

Tým je zaistená dopredná kompatibilita: príbeh napísaný pre Rea 1.0 funguje na parseri Rea 1.3. Príbeh používajúci funkcie Rea 1.3 funguje na parseri Rea 1.0 s elegantnou degradáciou.

Záznamy a úrovne zhody

Úroveň zhody určuje, čo implementácia spúšťa, nie čo hlási. Engine úrovne Core nevydáva žiadne záznamy — autorský kanál je vec nástrojov a embedder úrovne Core, ktorý nič nezapojí, nevyprodukuje nič. Nástroje úrovne Standard a Platform hlásia celý register.

Ak príbeh použije funkciu nad úrovňou, ktorú si implementácia nárokuje, funkcia neurobí nič a autor dostane meta/above-conformance-level s názvom funkcie a potrebnou úrovňou. Ten záznam je degraded, nie error: implementácia sa zachovala správne a autor sa dozvedá, ktoré z jeho rozhodnutí sa neprenieslo, nie že urobil chybu.


32. Prístupnosť

experimentalod 1.0WCAG 2.2 Level AA

Povinnosti na strane autora (alternatívny text, zmysluplný text volieb) platia už teraz; viaceré kritériá na strane platformy závisia od funkcií, ktoré sú ešte vo vývoji.

Rea mieri na zhodu s WCAG 2.2 na úrovni AA. Technickú implementáciu rieši platforma; špecifikácia definuje, čo musia a čo by mali poskytnúť autori.

Vstavané funkcie prístupnosti

Fungujú automaticky, bez akéhokoľvek zásahu autora:

FunkciaAko fungujePokryté kritériá WCAG
Výstup pre čítačky obrazovkyVšetok naratívny text je asistenčným technológiám sprístupnený v poradí čítania1.3.1, 1.3.2, 4.1.2
Ovládanie klávesnicouVoľby, odkazy a interaktívne prvky sa dajú zamerať a aktivovať klávesnicou2.1.1, 2.1.2
Správa zameraniaKeď sa objaví nový obsah (napr. po voľbe), zameranie sa presunie naň2.4.3, 2.4.7
Zameranie nie je zakrytéPrilepené prvky rozhrania (panely nástrojov, kooperatívne panely) nikdy úplne nezakryjú zameraný obsah2.4.11
Vysoký kontrastPlatforma presadzuje pomery kontrastu WCAG AA (4,5 : 1 text, 3 : 1 veľký text) vo všetkých témach1.4.3, 1.4.11
Obmedzený pohybAnimácie a prechody rešpektujú prefers-reduced-motion2.3.3
Veľkosť cieľaVšetky interaktívne ciele (voľby, tlačidlá, odkazy) majú aspoň 24 × 24 CSS pixelov2.5.8
Alternatívy k ťahaniuKaždá interakcia založená na ťahaní ponúka alternatívu jedným kliknutím2.5.7
Oznamovanie stavuNový naratívny obsah a zmeny stavu používajú živé oblasti ARIA pre čítačky obrazovky4.1.3
Ovládanie zvukuAutomaticky prehrávaný zvuk poskytuje viditeľné ovládanie pauzy a zastavenia do 3 sekúnd1.4.2
Nastaviteľné časovanieČasované udalosti ({timer}) ponúkajú pred spustením predĺženie, pauzu alebo vypnutie2.2.1
Konzistentná pomocMechanizmy pomoci sa objavujú na rovnakom relatívnom mieste na všetkých stránkach platformy3.2.6
Opakované zadávaniePlatforma automaticky dopĺňa už zadané údaje v rámci relácie čítania3.3.7
Prístupné prihlásenieOverenie totožnosti podporuje správcov hesiel a nevyžaduje testy kognitívnych schopností3.3.8
Kooperatívna prítomnosťUkazovatele prítomnosti čitateľov obsahujú aj nevizuálne signály (zvuk, vibrácia)1.3.3

Zodpovednosti autora

Autori prispievajú k prístupnosti existujúcou syntaxou:

  • Alternatívny text pri obrázkoch — vyžaduje ho syntax obrázka: [!alternatívny text < zdroj]. Obrázky bez alternatívneho textu spustia varovanie pri overovaní.
  • Hlasové a zvukové opisy — obsah {voice begin} je automaticky dostupný ako zvukový opis vizuálnych scén.
  • Zmysluplný text volieb — voľby by mali opisovať akciu, nie len „Možnosť A" alebo „Klikni sem".
  • Popisky pri časových médiách — príkazom {caption …} (pozri Sekciu 24) poskytnite textové alternatívy k zvuku a videu.

Cesty prístupnosti k interaktívnym prvkom

Prvok ReaCesta klávesnicouSprávanie čítačky obrazovky
Voľba (štandardná)Tab na zameranie, Enter/medzerník na výberOznámená ako tlačidlo s textom voľby
Voľba (sloveso — cieľ)Tab na zameranie, Enter/medzerník na výberOznámená ako tlačidlo so slovesom a opisom cieľa
Textové pole {input}Tab na zameranie, písanie na zadanieOznámené ako textový vstup s návestím z predchádzajúceho textu
Odpočet {timer}Nedá sa zamerať (dekoratívne)Zostávajúci čas oznamovaný v intervaloch cez živú oblasť
Karta (odhalenie/zavretie)Tab na zameranie, Enter na prepnutieOznámená ako rozbaliteľná oblasť so zhrnutím
Odkaz [text > url]Tab na zameranie, Enter na nasledovanieOznámený ako odkaz s viditeľným textom
Výzva na GPS zastávkuZameranie sa presunie na výzvu automatickyOznámená ako upozornenie s pokynom k polohe
Výzva na skenovanie QRZameranie sa presunie na výzvu automatickyOznámená ako upozornenie s možnosťou ručného zadania

Poznámky k návrhu

Čo Rea zámerne neobsahuje

Každá z týchto vecí bola zvážená a vylúčená. V indexe funkcií sa objavujú ako cancelled, takže rozhodnutie zostáva viditeľné a nie je objavované a preberané znovu.

  • Číslované a odrážkové zoznamy — zámerne nie sú súčasťou. Interaktívne príbehy formátovanie zoznamov nepoužívajú, * a - už sú značkami voľby a zberu a voľby túto úlohu plnia prirodzene. Štruktúrované údaje patria do poľa.
  • Značkovanie tabuliek — nie je súčasťou. Dátová tabuľka nie je rozprávačská konštrukcia a jej podpora by do prozaického jazyka vtiahla zarovnávanie stĺpcov a spájanie buniek.
  • Priepust HTML — trvalo vylúčené. Vkladanie surového značkovania by z každého príbehu urobilo plochu pre XSS a umožnilo by, aby značkovanie jedného autora rozbilo vykresľovanie u iného hostiteľa.
  • Štýlovanie cez CSS — trvalo vylúčené. Vizuálna prezentácia je zodpovednosťou platformy, aby príbeh nikdy nemohol prebiť vlastné predvoľby čitateľa — kontrast, veľkosť písma, tmavý režim.
  • Vkladanie programovacích jazykov — trvalo vylúčené. Príbeh je nedôveryhodný obsah; vloženie JavaScriptu, Pythonu či čohokoľvek iného by zničilo sandbox. Reálnu potrebu pokrývajú izolované rozšírenia .rext a rozšírenia hostiteľa dodané vkladateľom.
  • try / catch — vylúčené spolu s modelom chýb. Každé zotavenie je implicitné, pretože čitateľovi sa nikdy nesmie ukázať zlyhanie a autor by ho nikdy nemal musieť písať.

Vyriešené rozhodnutia o návrhu

RozhodnutieRiešenieZdôvodnenie
Syntax odkazov[text > url]Jednotná syntax hranatých zátvoriek, šípka ukazuje smer
Oddeľovač atribútovČiarkyUniverzálny oddeľovač parametrov aj položiek poľa, jednoznačné parsovanie
Oddeľovač v kotváchPodčiarkovník _V súlade s konvenciou pomenovania premenných
Pomenovanie funkciísnake_caseZhoduje sa so všetkými ostatnými identifikátormi Rea
Úrovne nadpisovNeobmedzená hĺbka #Platforma odlišne vykresľuje až N úrovní
Domény premennýchreader.*, story.*, world.* atď.Jasné menné priestory, údaje platformy len na čítanie
Pomenovanie premennýchdomena.nazov povinné pre všetky trvalé premennéSám o sebe zrozumiteľný stav; ľubovoľný Unicode okrem medzery a bodky
Syntax priradenia{set domena.premenna = hodnota}Výslovné, jednoznačné, priateľské k začiatočníkom
Operátor rovnosti= (jedno rovná sa)Jednoduchšie pre neprogramátorov. {set} zabraňuje nejednoznačnosti.
Syntax komentárov{comment text} a {comment begin}…{end comment}Jedna syntax, jednoriadková aj párová; blok otvára len presné {comment begin}
Značkovanie podčiarknutia{underline begin}text{end underline}Syntax príkazu — v súlade s prečiarknutím a neproporcionálnym písmom
Operátor regulárnych výrazovKľúčové slovo matches / !matchesSám o sebe zrozumiteľný, prefix ! pre negáciu v súlade s != a !in
Spájanie reťazcovOperátor + (dvojaká aritmetika a spájanie)Ak je čo len jeden operand reťazec, + spája; inak číselné sčítanie
Konverzia typovnumber(), string(), boolean(), integer()Výslovné konverzné funkcie; implicitné pretypovanie len vo výrazoch
Doménové typy@(lat, lng), datetime(), duration()Literál pre body, bežné konštruktory pre všetko, čo má rozlohu
Argumenty select a pluralPomenované parametre kľúč="hodnota"Zjednotené so syntaxou atribútov príkazov, žiadny zvláštny vzor objektu
Uloženie a postupPríkaz {checkpoint}Výslovné body uloženia; platforma ukladá automaticky na hraniciach kapitol a pri voľbách
Indexovanie políOd nulyV súlade so všetkými bežnými jazykmi (JS, Python, C). Prvá položka má index 0