Text UI ve Figmě je designový artefakt. Je to mockup copy, často psaný designéry spíše než product manažery, zřídka přezkoumávaný pro i18n. figmascope ho přesto extrahuje — protože i zástupný copy potřebuje klíč zdroje, pokud generujete kód, který bude nakonec lokalizován, a proces extrakce je místo, kde žije logika.

strings.json je artefakt, který mapuje ID zdrojů tečkové notace na doslovné hodnoty řetězců. Tento příspěvek pokrývá, jak jsou klíče generovány, co je filtrováno, co se stane při kolizi klíčů a jak se to mapuje na Android strings.xml a další i18n formáty.

Formát

{
  "speed.test": "Speed Test",
  "data.transfer.rate": "Data Transfer Rate",
  "start": "Start",
  "results.download": "Download",
  "results.upload": "Upload",
  "results.ping": "Ping",
  "unit.mbps": "Mbps",
  "settings.server.auto": "Auto Select"
}

Struktura je plochý objekt klíčovaný ID zdrojů tečkové notace. Hodnoty jsou doslovný textový obsah z Figmy. Vnořené tečkové cesty jsou sémanticky smysluplné — results.download a results.upload jsou ve stejné logické skupině — ale soubor je plochý JSON, nikoli vnořený. To odpovídá tomu, jak funguje Android strings.xml (ploché názvy zdrojů s tečkovou konvencí pro seskupení) a jak většina i18n knihoven (i18next, Rosetta atd.) zpracovává plochý klíčový jmenný prostor.

Jak jsou klíče generovány

Generování klíčů začíná od názvu vrstvy Figmy uzlu, nikoli od textového obsahu. Textový uzel pojmenovaný Data Transfer Rate Label s obsahem "Data Transfer Rate" generuje klíč z názvu vrstvy, nikoli z hodnoty.

Pipeline generování:

  1. Vezměte název vrstvy
  2. Aplikujte filtry sanitizeName: transliterujte kyrilická písmena, odstraňte obousměrné/řídicí znaky (rozsah Unicode U+202A–U+202E a podobné), odstraňte nealfanumerické a nemezerové znaky
  3. Převeďte na malá písmena a nahraďte mezery tečkami
  4. Ořízněte počáteční a koncové tečky

Takže "Data Transfer Rate Label""data.transfer.rate.label". V praxi designéři často pojmenovávají textové vrstvy bez závěrečného podstatného jména, takže "Data Transfer Rate""data.transfer.rate".

Krok transliterace kyrilice existuje, protože figmascope se používá se soubory Figmy napříč jazyky. Vrstva pojmenovaná Скорость se transliteruje na Skorost', pak se stane "skorost'" → po odebrání speciálních znaků → "skorost". Není to hezké, ale klíč je stabilní napříč běhy pro stejný název vrstvy.

Generování klíčů je z názvu vrstvy, nikoli z textové hodnoty. Dva textové uzly s identickým textovým obsahem, ale různými názvy vrstev, dostanou různé klíče. Dva textové uzly s různým textovým obsahem, ale stejným názvem vrstvy, vytvoří kolizi — zpracováno níže.

Filtry klíčů — co se vypustí

Ne každý textový uzel v souboru Figmy by měl být lokalizovatelný řetězec. figmascope filtruje před generováním klíčů:

Číselný filtr zasluhuje více vysvětlení. Designový mockup má často zástupná čísla: "42 ms" (ping), "150 Mbps" (rychlost stahování). "42 ms" prochází filtrem, protože není čistě číselný — stal by se klíčem "42.ms". Ale pravděpodobně byste chtěli extrahovat jen "ms" jako popis jednotky a vypočítat 42 za běhu. figmascope toto odvození neprovádí — bere celý text tak, jak je. Filtr krátkých řetězců vypustí samotné "ms" (2 znaky), ale zachová "42 ms" jako celý řetězec.

Toto je přiznané omezení. Text UI, který mísí šablonová data s doslovnými popisy, je obtížné automaticky rozložit. Generovaný kód by měl extrahovaný řetězec považovat za výchozí bod, nikoli za finální kopii.

Zpracování kolizí

Ke kolizi dojde, když dva různé textové uzly produkují stejný klíč, ale mají různé hodnoty. Například: vrstva pojmenovaná "Label" na obrazovce A obsahuje "Download" a vrstva pojmenovaná "Label" na obrazovce B obsahuje "Upload". Obě generují klíč "label".

Pravidlo kolize figmascope: vypusťte klíč zcela ze strings.json a vydejte varování v _meta.json:

// _meta.json
{
  "warnings": [
    "strings-collision:label"
  ]
}

Zachování jednoho libovolně by bylo špatné — tiše byste přeložili jeden ze dvou řetězců nesprávně. Zachování obou s disambiguovanými klíči (např. "label.1", "label.2") by bylo hádání při pojmenování, které nikomu neslouží. Vypuštění je upřímné.

IR zpracovává kolize čistě: když je klíč vypuštěn kvůli kolizi, figmascope prochází IR a odstraňuje pole stringRef ze všech listových uzlů, které na něj odkazovaly. Pole text (doslovná hodnota) zůstává. Agent vidí list s text, ale bez stringRef, a ví, že má použít doslovný text jako záložní — což je bezpečné, protože pravidlo CONTEXT.md říká pouze „použijte stringRef, pokud je přítomen."

// Před řešením kolize — dva listy se stejným klíčem, různým textem
{ "kind": "leaf", "text": "Download", "stringRef": "label" }
{ "kind": "leaf", "text": "Upload",   "stringRef": "label" }

// Po řešení kolize — klíč vypuštěn, text zachován
{ "kind": "leaf", "text": "Download" }
{ "kind": "leaf", "text": "Upload"   }

Varování vám říká, abyste opravili názvy vrstev ve Figmě. Vrstva pojmenovaná "Download Label" a "Upload Label" by produkovala odlišné klíče "download.label" a "upload.label" bez kolize.

Mapování na Android strings.xml

Android strings.xml používá ploché ID řetězcových zdrojů s podtržítky. Tečková notace z figmascope se mapuje čistě:

// strings.json
{
  "speed.test": "Speed Test",
  "data.transfer.rate": "Data Transfer Rate",
  "results.download": "Download"
}

// → strings.xml (generováno)
<resources>
    <string name="speed_test">Speed Test</string>
    <string name="data_transfer_rate">Data Transfer Rate</string>
    <string name="results_download">Download</string>
</resources>

Transformace je: nahraďte tečky podtržítky. To je úplná transformace. ID Android zdrojů neumožňují tečky; podtržítka jsou konvenční oddělovač. Klíč speed.test ve strings.json se stane R.string.speed_test v Kotlinu, což je to, na co omezení CONTEXT.md nasměruje agenta, když vidí stringRef: "speed.test".

// Omezení CONTEXT.md v akci
// IR list: { "text": "Speed Test", "stringRef": "speed.test" }
// Výstup agenta:
Text(text = stringResource(R.string.speed_test))

Mapování na jiné i18n formáty

Tečková notace je lingua franca pro i18n. Většina systémů ji přijímá přímo nebo potřebuje jen minimální transformaci:

FormátFormát klíčeTransformace z tečkové notace
Android strings.xml speed_test Nahraďte . za _
iOS Localizable.strings "speed.test" Žádná (tečková notace použita přímo)
i18next (JSON) Vnořené: { "speed": { "test": "..." } } Rozbalte ploché klíče do vnořené struktury
Flutter ARB speedTest Převeďte na camelCase

figmascope vydává formát tečkové notace. Transformace specifická pro cíl je zpracovávána downstream — buď agentem (pokud je cíl CONTEXT.md dostatečně explicitní) nebo malým konverzním skriptem.

Co strings.json neřeší

Upřímná poznámka o rozsahu: strings.json je extrahován z jakéhokoli textu, který v době exportu existuje ve Figmě. Není to ověřený soubor i18n zdrojů. Tři problémy, na které narazíte:

Zástupný text: Mockupy Figmy často používají Lorem Ipsum, "[Title Here]" nebo designérem napsaný copy, který nebyl přezkoumán. Extrahované řetězce jsou to, co je v souboru, přezkoumané nebo ne.

Dynamický obsah: Designy často ukazují "John Doe" nebo "42 Mbps" jako reprezentativní data. Nejsou to lokalizovatelné řetězce — jsou to šablonové hodnoty. figmascope nemůže rozlišit design-time data od design-time copy. Číselný filtr zachytí čistá čísla, ale smíšené řetězce jako "42 Mbps" jsou stále extrahovány.

Chybějící řetězce z filtrovaných uzlů: Pokud textový uzel selže filtrem (příliš krátký, pouze číselný, prázdný po sanitizaci), neobjeví se ve strings.json a IR list nebude mít stringRef. To je záměrné, ale znamená to, že pokrytí vašich řetězců závisí na kvalitě pojmenování vrstev ve Figmě.

Výstup je výchozí bod. Zkopírujte ho do svého i18n souboru, přezkoumejte ho oproti svým skutečným konvencím pojmenování zdrojů, smažte zástupné řetězce a přidejte klíče dynamického obsahu ručně. To je deset minut práce namísto ručního extrahování každého textového uzlu z Figmy. Vyzkoušejte extrahování řetězců z vlastního souboru na figmascope.dev.

Pro úplný přehled toho, jak stringRef proudí přes IR do generovaného kódu, viz IR pro každou obrazovku — Stack, Overlay, Absolute, Leaf. Pro to, jak jsou deklarována omezení upravující použití řetězců, viz Anatomie CONTEXT.md. Pro pracovní postup generování Jetpack Compose od začátku do konce viz Jetpack Compose z Figmy. Připraveni generovat vlastní strings.json? Použijte hlavní aplikaci na figmascope.dev.