Skip to content

Commit abc0cd5

Browse files
committed
fix: keep zero plural form in Apple XLIFF export
Apple XLIFF export dropped any plural form that CLDR doesn't define for the target locale, so an authored zero case (e.g. English zero/one/other) never made it into the exported stringsdict/xcstrings. AppleXliffExporter now keeps every form the user actually wrote in addition to the locale's CLDR forms, matching what the xcstrings exporter already does. Fixes #3074
1 parent f14e1b8 commit abc0cd5

2 files changed

Lines changed: 53 additions & 4 deletions

File tree

backend/data/src/main/kotlin/io/tolgee/formats/apple/out/AppleXliffExporter.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.tolgee.formats.PossiblePluralConversionResult
55
import io.tolgee.formats.apple.APPLE_CORRESPONDING_STRINGS_FILE_ORIGINAL
66
import io.tolgee.formats.apple.APPLE_FILE_ORIGINAL_CUSTOM_KEY
77
import io.tolgee.formats.apple.APPLE_PLURAL_PROPERTY_CUSTOM_KEY
8+
import io.tolgee.formats.getPluralFormsForLocale
89
import io.tolgee.formats.xliff.model.XliffFile
910
import io.tolgee.formats.xliff.model.XliffModel
1011
import io.tolgee.formats.xliff.model.XliffTransUnit
@@ -231,10 +232,13 @@ class AppleXliffExporter(
231232
languageTag: String,
232233
conversionResult: PossiblePluralConversionResult?,
233234
): Map<String, String> {
234-
if (conversionResult?.formsResult == null) {
235-
return emptyMap()
236-
}
237-
return io.tolgee.formats.populateForms(languageTag, conversionResult.formsResult)
235+
val forms = conversionResult?.formsResult ?: return emptyMap()
236+
// Apple's plural formats (stringsdict/xcstrings) accept any form the user actually wrote
237+
// (e.g. "zero"), not just the forms CLDR defines for the target locale, so we keep every
238+
// authored form in addition to filling in the ones CLDR expects (e.g. "many" for cs).
239+
val otherForm = forms["other"] ?: ""
240+
val allForms = getPluralFormsForLocale(languageTag) + forms.keys
241+
return allForms.associateWith { forms[it] ?: otherForm }
238242
}
239243

240244
private fun getResultXliffFile(

backend/data/src/test/kotlin/io/tolgee/unit/formats/apple/out/AppleXliffFileExporterTest.kt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,51 @@ class AppleXliffFileExporterTest {
308308
)
309309
}
310310

311+
@Test
312+
fun `keeps a zero plural form that is not in the target locale's CLDR forms`() {
313+
val built =
314+
buildExportTranslationList {
315+
add(
316+
languageTag = "en",
317+
keyName = "attendee_count",
318+
text = "{count, plural, zero {No participants} one {1 Participant} other {Many participants}}",
319+
) {
320+
key.isPlural = true
321+
key.custom = mapOf(APPLE_FILE_ORIGINAL_CUSTOM_KEY to "Localizable.xcstrings")
322+
}
323+
}
324+
val exporter = getExporter(built.translations, emptyList())
325+
val data = getExported(exporter)
326+
data.assertFile(
327+
"en.xliff",
328+
"""
329+
|<?xml version="1.0" encoding="UTF-8" standalone="no"?>
330+
|<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
331+
| <file datatype="plaintext" original="Localizable.xcstrings" source-language="tag" target-language="en">
332+
| <header>
333+
| <tool tool-id="tolgee.io" tool-name="Tolgee"/>
334+
| </header>
335+
| <body>
336+
| <trans-unit id="attendee_count|==|plural.one">
337+
| <source xml:space="preserve"/>
338+
| <target xml:space="preserve">1 Participant</target>
339+
| </trans-unit>
340+
| <trans-unit id="attendee_count|==|plural.other">
341+
| <source xml:space="preserve"/>
342+
| <target xml:space="preserve">Many participants</target>
343+
| </trans-unit>
344+
| <trans-unit id="attendee_count|==|plural.zero">
345+
| <source xml:space="preserve"/>
346+
| <target xml:space="preserve">No participants</target>
347+
| </trans-unit>
348+
| </body>
349+
| </file>
350+
|</xliff>
351+
|
352+
""".trimMargin(),
353+
)
354+
}
355+
311356
@Test
312357
fun `honors the provided fileStructureTemplate`() {
313358
val exporter =

0 commit comments

Comments
 (0)