CLI-Referenzverbatra tmxnew

verbatra tmx

Importiere einen TMX-Translation-Memory aus einem anderen Werkzeug oder exportiere den Memory dieses Projekts als TMX.

Maschinell übersetzte Seite

Diese Seite wurde automatisch übersetzt und kann daher Fehler oder seltsame Formulierungen enthalten. Die englische Version ist die maßgebliche Quelle. Das englische Original lesen.

Verfügbar ab 0.11.0

Dafür wird verbatra 0.11.0 oder neuer benötigt. Frühere Versionen haben es nicht, überprüfe daher deine installierte Version mit verbatra --version und aktualisiere, falls sie älter ist.

TMX ist das Austauschformat, das die gängigen Übersetzungsplattformen erzeugen und lesen. verbatra tmx import bringt einen Memory, den eine davon exportiert hat, in den Translation-Memory dieses Projekts, sodass ein späterer Lauf diese Strings wiederverwendet, statt erneut dafür zu bezahlen. verbatra tmx export schreibt den Memory dieses Projekts im selben Format wieder heraus, damit die Arbeit genauso leicht wieder gehen kann, wie sie gekommen ist.

Keine der beiden Richtungen ruft einen Provider auf, liest einen API-Key oder stellt eine Netzwerkanfrage. Jeder Wert kommt aus der Datei oder aus dem Memory, der ohnehin schon auf der Platte liegt.

Synopsis

verbatra tmx <direction> [file] [flags]

<direction> ist import oder export. [file] ist die TMX-Datei, die gelesen oder geschrieben wird, und ist standardmäßig verbatra-memory.tmx im Arbeitsverzeichnis.

Flags

FlagArgumentStandardWirkung
--cwd<path>aktuelles VerzeichnisKonfiguration und Memory von diesem Verzeichnis aus auflösen
--config<path>wird gesuchtdiese Konfigurationsdatei laden, statt eine zu suchen
--locales<list>alle konfiguriertenkommagetrennte Teilmenge der Ziel-Locales
--dry-runkeinsausnur beim Import, beim Export abgelehnt: prüfen und melden, ohne den Memory zu verändern
--overwritekeinsausnur beim Import, beim Export abgelehnt: eine importierte Einheit eine Übersetzung ersetzen lassen, die der Memory schon hat
--jsonkeinsauseinen JSON-Envelope auf stdout ausgeben, der das Ergebnis trägt, oder bei einem fehlgeschlagenen Lauf den Fehlercode; die menschenlesbare Fehlerzeile geht weiter auf stderr

Beispiele

# land another tool's memory in this project
verbatra tmx import legacy.tmx

# report what would land, change nothing
verbatra tmx import legacy.tmx --dry-run

# let the file win where it disagrees with what the project already holds
verbatra tmx import legacy.tmx --overwrite

# write the memory to verbatra-memory.tmx
verbatra tmx export

# only German, to a chosen path
verbatra tmx export out/memory.tmx --locales de

Was eine importierte Einheit erfüllen muss

Eine Datei aus einem anderen Werkzeug ist nicht vertrauenswürdige Eingabe, und eine Einheit, die es in den Memory schafft, kann wiederverwendet werden, ohne dass jemand noch einmal gefragt wird. Also wird nichts gespeichert, bevor es sich das verdient hat. Jede Übersetzung durchläuft dasselbe Integritäts-Gate wie Provider-Ausgabe und eine ausgefüllte Übersetzer-Übergabe, geprüft beim Eintritt in den Memory statt überlassen an den Lauf, der sie später liest:

  • ihre Platzhalter müssen zu den Platzhaltern ihres eigenen Quellsegments passen,
  • ihre Inline-HTML- oder XML-Tags müssen zu den Tags ihres eigenen Quellsegments passen, ein Tag, das die Quelle nie hatte (etwa ein eingeschleustes <img onerror>), wird also abgelehnt,
  • sie muss unter dem Adapter des konfigurierten Formats eine gültige ICU-Nachricht sein,
  • sie darf nicht in ausufernde Ausgabe statt einer Übersetzung gekippt sein,
  • sie darf nicht leer sein, wo die Quelle Text hat.

Dazu kommt: eine Einheit mit leerem Quellsegment bezeichnet überhaupt keinen String und wird ebenfalls abgelehnt. Inline-Markup (bpt, ept, ph, it) wird auf seinen Text eingeebnet, was die Platzhalterprüfung dann auffängt, falls das Markup etwas Wichtiges getragen hat. Ein sub-Element in diesem Markup ist ein eigener Textfluss, etwa ein Tooltip oder ein Alternativtext, und gehört nicht zum String des Segments. Sein Text wird deshalb weggelassen statt eingeebnet.

Nichts verschwindet stillschweigend. Jede Ablehnung wird nach Grund gezählt, ebenso jede Einheit, die der Leser gar nicht verwerten konnte, jede Einheit ohne Segment in deiner Quell-Locale, jede Einheit, deren Markup eingeebnet wurde, und jede Einheit, deren sub-Text weggelassen wurde.

Sprach-Tags zuordnen

Eine TMX-Datei schreibt ihre Sprachen so, wie das Werkzeug ihrer Autorin sie geschrieben hat, und das ist selten so, wie deine Konfiguration sie schreibt. Die Regel ist ausdrücklich, und sie rät nie:

  1. Beide Seiten werden kleingeschrieben und Unterstriche zu Bindestrichen gefaltet, sodass pt_BR, pt-br und pt-BR eine Locale sind. Eine exakte Übereinstimmung an dieser Stelle gewinnt.
  2. Andernfalls kann das Tag eine konfigurierte Locale erreichen, die ein Subtag-Präfix von ihm ist, sodass eine Datei in en-US in einem Projekt mit en landet. Sind mehrere konfigurierte Locales Präfixe des Tags, gewinnt die längste, wie beim Lookup nach RFC 4647: In einem Projekt mit de und de-AT landet eine Datei in de-AT-1996 bei de-AT und eine in de-CH-1901 bei de.
  3. Ein kürzeres Tag kann auch eine konfigurierte Locale erreichen, die mit ihm beginnt, aber nur, wenn jedes Subtag, das die Locale hinzufügt, eine Region oder eine Variante ist, nie eine Schrift. Eine Datei in de landet in einem Projekt, das nur de-DE konfiguriert hat, und pt in einem, das nur pt-BR konfiguriert hat, aber sr landet nie bei sr-Latn und zh nie bei zh-Hant-TW, weil ein Schrift-Subtag ein anderes Schriftsystem benennt. Eine konfigurierte Locale, die ein Präfix des Tags ist, hat immer Vorrang, und unter mehreren längeren gewinnt die nächstgelegene.
  4. Zwei Tags, deren Schrift- oder Regions-Subtags sich unterscheiden, passen nie zusammen. zh-CN wird nie als zh-TW gespeichert, sr-Latn nie als sr-Cyrl und de-AT nie als de-CH: So ein Tag wird als zu keiner konfigurierten Locale passend gemeldet, nicht geraten.
  5. Ein Tag wird nur dann als mehrdeutig gemeldet, wenn die konfigurierten Locales, die es erreichen könnte, nicht auf einer Präfix-Kette liegen. pt in einem Projekt mit pt-BR und pt-AO wird als mehrdeutig gemeldet, nicht derjenigen zugeschlagen, die zuerst kam.

Jedes Segment wird in einem Durchgang gegen die Quell-Locale und alle deine konfigurierten Ziel-Locales aufgelöst, nicht erst gegen die Quelle und danach gegen die Ziele. Genau das verhindert, dass eine regionale Ziel-Locale für das schlichte Quell-Tag gehalten wird, das sie erweitert: In einem Projekt mit der Quelle pt und pt-BR unter den Zielen ist das pt-BR-Segment genau dieses Ziel und nie eine zweite Lesart der Quelle. Das gilt auch, wenn du einen Lauf mit --locales einschränkst, denn die Auflösung sieht so oder so jede konfigurierte Locale.

Die Quellsegmente einer Einheit werden genauso gewichtet wie ihre Zielsegmente, siehe unten: Ein exaktes Tag schlägt ein Segment, das deine Quell-Locale nur über ein Subtag-Präfix erreicht, und zwei Segmente mit demselben Wert stimmen überein, sodass en "Save" neben en-US "Save" in einem Projekt mit en ganz normal importiert wird. Eine Einheit, deren gleichrangige Quellsegmente unterschiedliche Werte tragen, etwa en-US "Color" und en-GB "Colour", wird abgelehnt und gezählt, statt derjenigen zugeschlagen zu werden, die zuletzt kam. Eine Konfiguration, deren Quell-Locale und eine ihrer Ziel-Locales nach Normalisierung von Schreibweise und Trennzeichen dasselbe Tag sind, wird rundweg abgelehnt, weil sich kein Segment einer von beiden zuordnen ließe.

Zwei Zielsegmente, die auf dieselbe konfigurierte Locale auflösen, lassen nie stillschweigend das letzte gewinnen. Ein exaktes Tag schlägt immer ein Segment, das die Locale nur über ein Subtag-Präfix erreicht: In einem Projekt mit de speichert eine Einheit mit de "Straße" und de-CH "Strasse" also "Straße". Tragen zwei gleichrangige Segmente unterschiedliche Werte, etwa de-CH "Strasse" und de-AT "Straße", wird aus dieser Einheit für diese Locale nichts gespeichert, und die Einheit wird für diese Locale in der Zusammenfassung und im --json-Ergebnis als Konflikt gezählt. Die anderen Locales der Einheit landen trotzdem, und zwei Segmente mit demselben Wert sind kein Konflikt.

Einheiten, die der Leser nicht verwerten konnte, Einheiten ohne Quellsegment, Einheiten mit eingeebnetem Markup und tu-Elemente außerhalb des ersten body der Datei werden ebenfalls gezählt. Deklariert der Header ein srclang, das nicht deine Quell-Locale ist, wird das gemeldet statt übergangen.

Tags, die zu nichts Konfiguriertem passen, werden pro Tag gezählt und gemeldet. Eine Datei voller Sprachen, die du nicht übersetzt, sagt dir das also, statt wie ein leerer Import auszusehen.

Wenn Datei und Memory sich widersprechen

Der eigene Memory des Projekts gewinnt. Hat der Memory für dieselbe Quelle und Locale schon eine andere Übersetzung, wird die importierte abgelehnt und als behalten gezählt. Mit --overwrite drehst du das um und lässt die Datei gewinnen.

Innerhalb einer Datei gewinnt die erste Einheit zu einer Quelle, spätere Wiederholungen werden als Duplikate gezählt.

Dieselbe Datei ein zweites Mal zu importieren ändert deshalb nichts und schreibt gar keine Datei.

Importierte Einheiten und deine Konfiguration

Importierte Einheiten werden unter dem aktuellen Konfigurations-Fingerprint des Projekts gespeichert, demselben Schlüssel, den auch ein echter Lauf schreibt. Das ist Absicht: ein importierter Memory wird genau dann wiederverwendet, wenn die Konfiguration passt, die ihn verbrauchen würde, und hört auf zu passen, sobald sich Provider, Modell, Tonfall oder Glossar ändern. Genau dafür gibt es die Fingerprint-Schicht. Importiere die Datei nach so einer Änderung erneut.

Wurde die Memory-Datei von einem neueren verbatra geschrieben als dem, das du ausführst, lässt der Import sie unangetastet und sagt es dir, statt eine Datei zu schreiben, der das neuere Build danach misstrauen müsste.

Importierte Einheiten und unscharfe Wiederverwendung

Eine Folge ist es wert, klar gesagt zu werden, weil keine Prüfung zur Importzeit sie abfangen kann. Der Quelltext einer akzeptierten Einheit wird in den Quelltext-Index des Memorys geschrieben, und genau daran misst die unscharfe Wiederverwendung einen geänderten String. Eine importierte Quelle, die sich von einem String in deinem Projekt unterscheidet, kann deshalb für diesen String ausgeliefert werden. Genau das heißt Ähnlichkeit.

Eine importierte Quelle, die mit einem deiner Strings identisch ist, aber anders hasht, ist gar nicht erreichbar. Die unscharfe Wiederverwendung verwirft jeden Kandidaten, dessen normalisierter Quelltext dem gesuchten String gleicht. Trägt dein Eintrag also eine Beschreibung, eine Bedeutung oder ein Plural-Flag, das eine TMX-Einheit nicht tragen kann, unterscheiden sich die Hashes, der identische Text schließt den unscharfen Kandidaten aus, und der String geht wie gewohnt an den Provider.

So eine Wiederverwendung unterliegt weiterhin dem Integritäts-Gate gegen deinen echten Eintrag und wird in der Lauf-Zusammenfassung als Review-Flag FUZZY_CACHE_REUSE gemeldet, ist also sichtbar und nicht still. Soll ein importierter Memory auf diesem Weg gar nicht erreichbar sein, lass fuzzyCache aus deiner Konfiguration weg: ohne sie wird nur ein exakter Content-Hash-Treffer je wiederverwendet.

Was der Export schreibt

Ein tu-Element pro eigenständigem Quellstring, mit dem Quellsegment und je einem Zielsegment pro exportierter Locale, unter einem TMX-1.4b-Header, der srclang, creationtool, creationtoolversion, segtype und o-tmf nennt. Geschrieben werden nur Einträge unter dem aktuellen Konfigurations-Fingerprint, also dieselbe Menge, die ein Lauf wiederverwenden würde.

Sprach-Tags werden in BCP-47-Form geschrieben, egal wie deine Konfiguration sie schreibt: Unterstriche werden zu Bindestrichen, die Sprache klein, eine Schrift mit großem Anfangsbuchstaben und eine Region groß. Ein Projekt mit en_US und pt_BR schreibt srclang="en-US" und xml:lang="pt-BR", was andere Werkzeuge akzeptieren und was sich unverändert wieder in dasselbe Projekt importieren lässt. Wie verbatra seinen eigenen Memory schlüsselt, ändert sich nicht.

Ein Zeichen, das XML 1.0 überhaupt nicht darstellen kann, etwa ein Steuerzeichen oder ein einzelnes Surrogat, wird aus dem Segmenttext entfernt, damit ein konformer Parser die Datei lesen kann. Wie viele entfernt wurden, steht in der Zusammenfassung und im --json-Ergebnis.

Ein leerer Memory ergibt eine gültige, leere TMX-Datei statt eines Fehlers.

Ein Eintrag, zu dem der Memory keinen Quelltext hat, lässt sich nicht schreiben, denn TMX kennt keine Einheit ohne Quellsegment. Das passiert nur bei Einträgen, die aus einem Cache übernommen wurden, der noch vor dem Speichern des Quelltexts geschrieben wurde; sie werden ausgelassen und gezählt und füllen sich auf, sobald spätere Läufe diese Strings wieder anfassen.

Exit-Codes

CodeBedeutung
0die Datei wurde gelesen oder geschrieben
2nicht ausführbar: ein Konfigurationsfehler, eine fehlende oder unlesbare Datei, eine Datei, die kein gültiges TMX ist, oder ein Aufruffehler

Eine Datei, die zu groß ist, fehlerhaft ist, kein TMX-Dokument ist oder eine XML-Entity deklariert, wird mit einem strukturierten Fehler abgelehnt, der benennt, was schiefging. Hat das Problem einen Ort in der Datei, nennt die Meldung auch Zeile und Spalte und, innerhalb einer Übersetzungseinheit, welche Einheit es war (ab 1 gezählt), sodass line 9, column 29, unit 2 dich zum zweiten tu führt. Mit --json steht dieselbe Meldung im Fehler-Envelope, und wer das SDK aufruft, liest denselben Ort mit tmxErrorLocation(error) als strukturierte Daten aus. Entity-Deklarationen und interne DTD-Subsets werden rundweg abgelehnt, sodass weder eine externe Entity-Referenz noch eine unbegrenzte Expansion je erreicht wird, und die schlichte externe Doctype-Zeile, die echte Werkzeuge schreiben, wird verworfen statt geladen.

Übersprungene oder abgelehnte Einheiten lassen den Lauf nicht scheitern. Sie werden gemeldet, denn ein Memory aus der Praxis trägt fast immer von beidem etwas.

Weiterführend

  • Der Cache erklärt, was der Translation-Memory ist und unter welchem Schlüssel er abgelegt wird.
  • Menschliche Übersetzung behandelt die Übergabe als xlsx, CSV und TSV, und das ist etwas anderes: ein Ausschnitt des offenen Deltas pro Locale für eine Übersetzerin, nicht der ganze Memory.
  • Übersetzungssicherheit erklärt die Prüfungen, die eine importierte Einheit bestehen muss.
Edit on GitHub