Chanjung Kim
8 months ago
2 changed files with 114 additions and 1 deletions
@ -0,0 +1,98 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2024 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
import groovy.util.Node |
||||||
|
import groovy.xml.XmlParser |
||||||
|
import org.gradle.api.DefaultTask |
||||||
|
import org.gradle.api.file.DirectoryProperty |
||||||
|
import org.gradle.api.file.RegularFileProperty |
||||||
|
import org.gradle.api.tasks.* |
||||||
|
|
||||||
|
/** |
||||||
|
* Reads a pluralization rules XML file from Unicode's CLDR and generates a Kotlin file that holds the XML content as |
||||||
|
* arrays. This Task is required for quantity string resource support. |
||||||
|
*/ |
||||||
|
@CacheableTask |
||||||
|
abstract class GeneratePluralRuleListsTask : DefaultTask() { |
||||||
|
@get:InputFile |
||||||
|
@get:PathSensitive(PathSensitivity.RELATIVE) |
||||||
|
abstract val pluralsFile: RegularFileProperty |
||||||
|
|
||||||
|
@get:OutputDirectory |
||||||
|
abstract val outputDir: DirectoryProperty |
||||||
|
|
||||||
|
@TaskAction |
||||||
|
fun generatePluralRuleLists() { |
||||||
|
val outputDir = outputDir.get().asFile |
||||||
|
if (outputDir.exists()) { |
||||||
|
outputDir.deleteRecursively() |
||||||
|
} |
||||||
|
outputDir.mkdirs() |
||||||
|
|
||||||
|
val pluralRuleLists = parsePluralRuleLists() |
||||||
|
val pluralRuleListIndexByLocale = pluralRuleLists.flatMapIndexed { idx, pluralRuleList -> |
||||||
|
pluralRuleList.locales.map { locale -> |
||||||
|
locale to idx |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val fileContent = """ |
||||||
|
package org.jetbrains.compose.resources.intl |
||||||
|
|
||||||
|
internal val cldrPluralRuleListIndexByLocale = mapOf( |
||||||
|
${pluralRuleListIndexByLocale.joinToString { (locale, idx) -> "\"$locale\" to $idx" }} |
||||||
|
) |
||||||
|
|
||||||
|
internal val cldrPluralRuleLists = arrayOf( |
||||||
|
${ |
||||||
|
pluralRuleLists.joinToString { pluralRuleList -> |
||||||
|
""" |
||||||
|
arrayOf(${ |
||||||
|
pluralRuleList.rules.joinToString { rule -> |
||||||
|
"PluralCategory.${rule.count.uppercase()} to \"${rule.rule}\"" |
||||||
|
} |
||||||
|
}) |
||||||
|
""".trimIndent() |
||||||
|
} |
||||||
|
} |
||||||
|
) |
||||||
|
""".trimIndent() |
||||||
|
|
||||||
|
outputDir.resolve("generated.kt").writeText(fileContent) |
||||||
|
} |
||||||
|
|
||||||
|
private fun parsePluralRuleLists(): List<PluralRuleList> { |
||||||
|
val parser = XmlParser(false, false).apply { |
||||||
|
setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false) |
||||||
|
setFeature("http://apache.org/xml/features/disallow-doctype-decl", false) |
||||||
|
} |
||||||
|
val supplementalData = parser.parse(pluralsFile.get().asFile) |
||||||
|
val pluralRuleLists = supplementalData.children().filterIsInstance<Node>().first { it.name() == "plurals" } |
||||||
|
|
||||||
|
return pluralRuleLists.children().filterIsInstance<Node>().map { pluralRules -> |
||||||
|
val locales = pluralRules.attribute("locales").toString().split(' ') |
||||||
|
PluralRuleList( |
||||||
|
locales, |
||||||
|
pluralRules.children().filterIsInstance<Node>().map { pluralRule -> |
||||||
|
PluralRule( |
||||||
|
pluralRule.attribute("count").toString(), |
||||||
|
// trim samples as not needed |
||||||
|
pluralRule.text().split('@')[0].trim(), |
||||||
|
) |
||||||
|
} |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private data class PluralRuleList( |
||||||
|
val locales: List<String>, |
||||||
|
val rules: List<PluralRule>, |
||||||
|
) |
||||||
|
|
||||||
|
private data class PluralRule( |
||||||
|
val count: String, |
||||||
|
val rule: String, |
||||||
|
) |
Loading…
Reference in new issue