Menschliche Übersetzung
Exportiere unübersetzte Strings in eine Excel-Arbeitsmappe, gib sie an eine Übersetzerin und importiere das Ergebnis mit denselben Sicherheitsprüfungen wie bei einem automatischen Lauf zurück.
Maschinell übersetzte Seite
Nicht jeder String gehört zu einem Provider. Marketingtexte, juristische Texte und die wichtigsten Sprachen wollen oft eine menschliche Übersetzerin. verbatra löst das mit einem Arbeitsmappen-Roundtrip: exportiere die zu übersetzenden Strings in eine formatierte Excel-Datei, gib sie weiter, dann importiere die ausgefüllte Datei zurück in deine Locale-Dateien.
Beide Richtungen treibt derselbe Diff. Export wählt genau die Keys, die ein automatischer Lauf übersetzen würde (die neuen und geänderten), und Import führt dieselben Platzhalter- und ICU-Prüfungen aus wie translate; ein von Hand getippter Wert, der einen Platzhalter bricht, wird also zurückgehalten und gemeldet statt geschrieben.
Der Roundtrip
# 1. Export the strings that need translating
verbatra export
# 2. A translator fills the Translation column and sends the file back
# 3. Import the filled workbook
verbatra import verbatra-translations.xlsxStandardmäßig schreibt export verbatra-translations.xlsx in das Arbeitsverzeichnis. Import liest die Datei zurück, validiert jede ausgefüllte Zeile, schreibt die bestandenen Werte in deine Locale-Dateien und rückt die Baseline der Lock-Datei genau für die akzeptierten Keys vor, so wie es ein translate-Lauf täte.
Was in der Arbeitsmappe landet
Die Datei beginnt mit einem Blatt Instructions, danach folgt ein Datenblatt pro Ziel-Locale, benannt nach dem Locale (de, fr, ...). Weil das Locale über den Blattnamen zurückreist, wird ein Locale, das kein gültiger Excel-Blattname sein kann, abgelehnt, bevor die Arbeitsmappe gebaut wird: länger als 31 Zeichen, mit einem der Zeichen : \ / ? * [ ], gleich Instructions in beliebiger Schreibung, oder ohne Beachtung der Groß- und Kleinschreibung gleich einem anderen Ziel-Locale.
Jedes Datenblatt teilt dieselben Spalten, in dieser Reihenfolge:
| Spalte | Bearbeitbar | Zweck |
|---|---|---|
Key | nein | Der gepunktete Key-Pfad. Die einzige Identität, die eine Zeile auf einen String zurückführt. |
Source | nein | Der Wert im Quell-Locale, als Referenz. |
Current translation | nein | Der bestehende Zielwert, falls vorhanden. |
Status | nein | new (noch keine Übersetzung), changed (die Quelle hat sich seit der letzten Übersetzung geändert) oder unchanged (bereits aktuell, nur mit --include-unchanged enthalten). |
Translation | ja | Die einzige Zelle, die die Übersetzerin ausfüllt. |
Source hash | nein | Ausgeblendet. Der beim Export erfasste Hash des Quellinhalts, mit dem eine nach dem Export geänderte Quelle erkannt wird. |
Context | nein | Entwicklerkontext, wenn das Quellformat welchen trägt (Flutter ARBs @key.description, XLIFFs <note>). Nur Referenz, wird nie importiert. |
Review status | nein | ok oder review: ob die Review-Heuristiken von verbatra die aktuelle Übersetzung für einen zweiten Blick markiert haben. Nur ein Hinweis, nie ein Gate. |
Review reasons | nein | Kommagetrennte Grund-Labels, die einen review-Status erklären (zum Beispiel length-ratio-outlier, equals-source). |
Die Zeilen sind nach Key sortiert, die Kopfzeile ist fixiert, die Spalte Source hash ist ausgeblendet, und jede Spalte außer Translation ist per Blattschutz gesperrt und grau hinterlegt. Die Spalte Translation nutzt Excels Textformat; ein Wert wie 007 oder einer, der mit = beginnt, bleibt also wörtlicher Text, statt in eine Zahl oder Formel umgedeutet zu werden.
Die Übergabe
Was eine Übersetzerin wissen muss, passt in wenige Zeilen (und steht noch einmal auf dem Instructions-Blatt der Arbeitsmappe):
- Fülle die Spalte
Translation, sonst nichts. Der Blattschutz erzwingt das. - Benenne die Sprach-Tabs nicht um, lösche und ordne sie nicht neu. verbatra ordnet jedes Tab über seinen exakten Namen einem Locale zu, ein umbenanntes oder fehlendes Tab wird also gemeldet und dieses Locale nicht importiert.
- Zeilen sortieren und filtern ist in Ordnung: Import ordnet Zeilen über
Keyzu, nie über die Position. Die Spalten müssen bleiben, wo sie sind; Import liest sie nach Position und verifiziert die ÜberschriftenKeyundSource hash. - Eine leere
Translation-Zelle heißt "noch nicht übersetzt". Import überspringt sie und schreibt nie einen leeren String; eine halb ausgefüllte Arbeitsmappe kann also jetzt zurückkommen und der Rest später. Eine Zelle, die nur Leerzeichen enthält, zählt als leer. Um einen bestehenden Wert bewusst zu leeren (auf leer zu setzen), tippe genau[[CLEAR]]in die Zelle.
Was der Import akzeptiert
Import ist kein blindes Einfügen. Jede ausgefüllte Zeile wird gegen das laufende Projekt geprüft, bevor irgendetwas geschrieben wird:
- Quelldrift: der verborgene
Source hashwird mit der aktuellen Quelle verglichen. Hat sich der Quellstring nach dem Export geändert, wird die Zeile zurückgehalten; du überschreibst also nie eine aktuelle Quelle mit der Übersetzung einer alten. - Platzhalter-Integrität: die Übersetzung muss exakt dieselben Platzhalter tragen wie ihre Quelle. Lass
{name}fallen oder erfinde{total}, und die Zeile wird zurückgehalten. - ICU-Gültigkeit: eine ICU-Nachricht muss strukturell gültig bleiben, mit denselben Argumentnamen; nur der menschenlesbare Text darf sich ändern.
- Unbekannte Keys: eine ausgefüllte Zeile, deren Key weder in der aktuellen Quelle noch in der aktuellen Zieldatei existiert (etwa ein von Hand eingetippter), lässt das ganze Blatt dieses Locales fehlschlagen, weil der Roundtrip gebrochen ist. Eine ausgefüllte Zeile, deren Key nur im Ziel existiert (ein verwaister Key), wird stillschweigend nicht geschrieben.
- Context ist nie eine Übersetzungsquelle: Import ignoriert die Spalte
Contextvollständig, und eine Arbeitsmappe, die vor der Einführung dieser Spalte exportiert wurde, importiert weiterhin normal.
Zurückgehaltene Zeilen erscheinen in der Lauf-Zusammenfassung unter dem Locale, zu dem sie gehören; akzeptierte Zeilen werden geschrieben und ihre Lock-Baseline rückt vor. Eine zurückgehaltene oder leere Zeile behält ihre bisherige Baseline, der Key wird also weiter exportiert, bis er wirklich erledigt ist. Eine leere Zeile, deren Quelle seit dem Export gedriftet ist, wird zusätzlich mit einer BLANK_ROW_BASELINE_RETAINED-Notice gemeldet, damit die Drift sichtbar bleibt.
Import weist außerdem strukturelle Befunde pro Locale aus, statt an ihnen abzubrechen: eine changed-Zeile, die die Übersetzerin leer gelassen hat (als unfilled gemeldet, weiter ausstehend), eine Arbeitsmappen-Zeile, die der Reader nicht parsen konnte (nach Zeile und Spalte gemeldet), und ein doppelter Key (das erste Vorkommen gewinnt und wird importiert, jedes spätere wird gemeldet). Keiner dieser Befunde lässt das Blatt für sich allein fehlschlagen.
Jedes Datenblatt ist ein Locale in der Zusammenfassung: ein Blattfehler (ein erfundener Key, ein Blatt für ein Locale, das nicht in deiner Konfiguration steht, oder ein konfiguriertes Locale, dessen Tab ganz fehlt, weil es umbenannt, gelöscht oder herausgeschoben wurde) lässt dieses Locale fehlschlagen und lässt die anderen unberührt. Import teilt den Exit-Code-Vertrag von translate: 0, wenn jedes Blatt erfolgreich ist, 1, wenn eines fehlschlägt, 2, wenn der Lauf nicht starten konnte. Eine manuelle Übergabe fügt sich damit in dieselben CI-Prüfungen ein wie ein automatischer Lauf.
Erst der Dry-Run
Validiere eine zurückgekommene Arbeitsmappe und sieh dir an, was geschrieben würde, ohne eine einzige Datei anzufassen:
verbatra import verbatra-translations.xlsx --dry-runAuswählen, was exportiert wird
Standardmäßig enthält der Export nur die fehlenden und geänderten Strings, also die Arbeit, die wirklich ansteht:
# Only the German and French sheets
verbatra export --locales de,fr
# Also include strings that are already up to date
verbatra export --include-unchanged
# Write to a specific path
verbatra export --out handoff/round-2.xlsxGreif zu --include-unchanged, wenn eine Übersetzerin den vollen Kontext eines Locales will, nicht nur das Delta. Alle Flags stehen unter verbatra export.
Die Review-Spalten
Review status und Review reasons sind eine nicht blockierende Schicht über den Prüfungen oben: die Heuristiken von verbatra, um eine Übersetzung zu erkennen, die strukturell in Ordnung ist, aber einen zweiten Blick verdient. Diese Spalten halten nie eine Zeile zurück, und Import liest sie nie; ein Flag verschwindet nur, indem du die Übersetzung reparierst. Beide Spalten werden beim Export frisch aus der Quelle und den aktuellen Zielwerten berechnet:
length-ratio-outlier: die Übersetzung ist deutlich kürzer oder länger als ihre Quelle.equals-source: die Übersetzung ist identisch mit der Quelle.glossary-term-missed: ein konfigurierter Glossarbegriff hat es nicht in die Übersetzung geschafft.integrity-reordered: die Platzhalter stimmen, landeten aber in anderer Reihenfolge als in der Quelle.
Ein fünfter Grund, provider-degraded, existiert nur zur Übersetzungszeit (eine DeepL-Degradations-Notice auf dem Batch, aus dem ein Key kam); da Export nie einen Provider aufruft, erscheint er nie auf einer exportierten Zeile. Eine Zeile ohne bisherige Übersetzung exportiert immer ok; es gibt nichts zu reviewen. In Übersetzungssicherheit steht, wie diese Flags mit den harten Platzhalter- und ICU-Prüfungen zusammenhängen.
Aus dem SDK
Die CLI-Befehle verpacken zwei SDK-Funktionen, exportWorkbook und importWorkbook:
import { exportWorkbook, importWorkbook, loadConfig } from "@verbatra/sdk";
const config = await loadConfig();
// Write a workbook of the strings that need translating
await exportWorkbook({ config });
// ...later, import the filled file back
const summary = await importWorkbook({ config, workbook: "verbatra-translations.xlsx" });Beide nehmen die validierte Konfiguration aus loadConfig, und importWorkbook gibt dieselbe RunSummary zurück wie translate. Die Arbeitsmappe selbst wird von @verbatra/exchange gebaut und geparst, einem internen Paket, das du nur über diese beiden Funktionen erreichst.
Weiter
verbatra export: jedes Export-Flag und der Bericht, den es ausgibt.verbatra import: jedes Import-Flag, die Lauf-Zusammenfassung und die Exit-Codes.- Übersetzungssicherheit: die Platzhalter- und ICU-Prüfungen, die jeden Schreibvorgang schützen, manuell wie automatisch.
GitHub Action
Führe verbatra translate in GitHub Actions mit der Composite Action aus: Eingaben, Secret-Verdrahtung, Annotationen und die Job-Zusammenfassung.
Review in Studio
Starte Verbatra Studio, arbeite die Review-Warteschlange ab, korrigiere Einträge direkt und lass markierte Keys aus dem lokalen Dashboard neu übersetzen.