Openapoc: Ersetzen Sie tinyfmt durch fmt (https://github.com/fmtlib/fmt)

Erstellt am 16. Sept. 2019  ·  9Kommentare  ·  Quelle: OpenApoc/OpenApoc

fmt:

  • Erlaubt Positionsargumente, um die Übersetzung zu erleichtern (z. B. könnte das Zeichenfolgenformat ("Do {0} to {1}", thing1, thing2) "übersetzt" werden als "Do {1} to {0}", um eine unterschiedliche Reihenfolge im . zu ermöglichen Satz
  • Derzeit im Entwurf des c++20-Standards, also ziemlich wahrscheinlich bald in Standardbibliotheken (weniger Abhängigkeiten und breitere Verwendung und Programmiererpräsenz ist gut)
  • Schnellere Kompilierzeiten
  • Schnelle Laufzeiten

im Vergleich zu Tinyformat.

Enhancement Feature Request

Alle 9 Kommentare

Wird daran gearbeitet?

Ich habe den anfänglichen Port lokal funktionieren lassen, hatte aber keine Zeit, ihn zu polieren und richtig zu testen (z mit xgettext als Build-Ziel usw.)

Es enthüllte auch eine Reihe von "schlechten" Übersetzungsrichtlinien - z. B. Zusammenfügen übersetzter Textfragmente, anstatt jeweils die falsche Zeichenfolge zu erstellen (z. %s Ding ist %d aus "), Objekt, Anzahl), format(tr(aus "%d Gesamt"), Zahl));

Was für Übersetzer zu den völlig nutzlosen Strings führen würde:
"%s %s"
"%s Ding ist %d"
"von %d insgesamt"

wenn es wirklich als ein einzelner Aufruf übersetzt werden sollte, sollte die extrahierte Zeichenfolge sein:
"%s Ding ist %d von %d insgesamt" (oder "{0} Ding ist {1} von {2} total" in der fmtlib-Methode)

Soweit ich weiß, muss es zwei unterschiedliche Formatierungs-Subsysteme geben:

  1. {fmt} basierte Protokollierung (da es IMO wenig Vorteile bringt, potenziell sich ständig ändernde Protokollnachrichten zu übersetzen, und würde das Routing über boost::locale Leistung beeinträchtigen.
  2. boost::locale::format für lokalisierbare UI-Strings (da Pluralformen unterstützt werden).

Ich würde vorschlagen, sie in kleinen Schritten zu implementieren: zuerst zu {fmt} wechseln und dann mit lokalisierbaren Strings umgehen.

Ich bin mir nicht sicher, ob boost::locale für uns in Zukunft wirklich so nützlich sein wird - es ist großartig für statische Anwendungen mit statischen Übersetzungsdatenbanken, aber ich habe Schwierigkeiten herauszufinden, wo ich mich in seine Nachrichtendatenbank einklinken kann, um neue Nachrichten hinzuzufügen Modifikationen.

Ich denke, es ist nur möglich, eine komplett neue Datenbank in einer neuen Übersetzungsdomäne hinzuzufügen, und dann geraten wir in Probleme, herauszufinden, mit welcher Domäne wir einen String übersetzen sollten, ohne etwas wie /all/mod-Domänen der Reihe nach zu versuchen, bis wir einen Treffer finden

Mein derzeitiger Plan ist es also, jede der Aufgaben zu trennen - ähnlich wie Sie es erwähnt haben:

  • Verwenden Sie {fmt} für alle Protokolle und internen Strings (es wird an einigen Stellen zum Erstellen von IDs usw. verwendet - etwas, das wir ausdrücklich nicht übersetzen möchten)
    -- Dies wird erhebliche Zeichenfolgenänderungen vom %printf-Stil zu {fmt} mit sich bringen, aber idealerweise keine Auswirkungen auf die Übersetzungen haben
  • Verdrahten Sie die .pot-Generierung automatisch mit xgettext
    -- Dies wird wahrscheinlich einen Großteil der "schlechten" Übersetzungsarbeit hervorheben - einige Leute scheinen mit den von OG .exe extrahierten Strings als "goldene" Übersetzungsnachrichtenquelle davongelaufen zu sein, obwohl die Strings von openapoc stellenweise sehr unterschiedlich aufgebaut sind
  • Überprüfen Sie die Quelle auf "schlechte" Übersetzungs-String-Konstruktion (wie das oben erwähnte Beispiel) oder auf Strings, die nicht übersetzt werden sollten (Logs, interne ID-Strings usw.) mit ::format())
    -- Dies sollte durch den vorherigen Schritt erleichtert werden, da es in der generierten .pot offensichtlich sein sollte
  • Konvertieren Sie alle /translated/-Strings vom %printf-Stil in den {fmt}/boost::locale-Stil (ich denke, sie sind funktional gleich, da wir derzeit keine Pleuralanmerkungen oder ähnliches haben)
    -- Dadurch werden so ziemlich alle aktuellen Übersetzungsarbeiten ungültig - es lohnt sich also wahrscheinlich nicht, Übersetzungsaktualisierungen zwischen den Phasen durchzuführen

Ich habe so ziemlich alle oben genannten Stages lokal in verschiedenen Bundesstaaten - es macht wahrscheinlich Sinn für mich, sie in einen brauchbaren Zustand zu bringen, und jetzt habe ich ein bisschen Zeit an diesem langen Wochenende, das wird wohl meine nächste Aufgabe sein :)

Sobald das alles erledigt ist, können wir uns Gedanken darüber machen, wie Mods funktionieren würden, die neue Strings hinzufügen

Konvertieren Sie alle /translated/-Strings vom %printf-Stil in den {fmt}/boost::locale-Stil (ich denke, sie sind funktional gleich, da wir derzeit keine Pleuralanmerkungen oder ähnliches haben)

Eigentlich sehen sie nur ähnlich aus -- boost::locale bietet eine 1-basierte Indexierung und eine stark unterschiedliche Formatierungsgrammatik. Wenn nicht für Pluralformen, würde ich {fmt} da ich seine Unterstützung für benannte Argumente als gute Hilfe für Übersetzer finde, die wertvollen Kontext hinzufügen, z.

Delay = {seconds}
Range = {meters:2.1}m.

Obwohl ich Unterstützung für Pluralformen viel wertvoller finde.

Ja, ich erinnere mich an die Indizierung, die mich anfangs umgeworfen hat :)

TBH für die Zukunft Ich denke, das boost::locale-Format ist gut, ich bin sicher, wir können die Mod-Kontextprobleme in Zukunft beheben.

Oder zumindest dann, wenn wir das "nächste" Problem finden, werden alle übersetzten Strings in einem viel vernünftigeren Format vorliegen und nicht mit nicht übersetztem formatiertem Text vermischt.

Außerdem sollte ehrlich gesagt die gesamte USstring-Klasse eine Reihe von Helfern um einen std::basic_string . sein- aber das sieht so aus, als ob es erst ab c++20 zuverlässig sein wird.

Ich bin versucht, einfach alles durch einen std::string zu ersetzen (IE std::basic_string), aber dann verlieren wir die Typsicherheit für "known utf8" vs "array of bytes" - aber ich bin mir nicht sicher, ob wir das wirklich verwenden. Wir müssten nur bei Schnittstellen vorsichtig sein, aber wir sind heute nicht vorsichtig, sondern rufen einfach .cStr()/.str() ohne echte Konvertierung als "Ausstieg" auf.

Die IT "funktioniert" derzeit "zufällig", da ich dazu neige, auf Plattformen zu testen, die bereits utf8 in ihren System-APIs verwenden - aber ich vermute, es wird derzeit kaputt gehen, wenn wir heute versuchen, etwas zu tun, wie zum Beispiel einen Dateinamen mit einem Nicht-ASCII-Pfad unter Windows zu öffnen

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen