You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

134 lines
5.1 KiB

/*
* 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.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:OutputFile
abstract val outputFile: RegularFileProperty
@get:OutputFile
abstract val samplesOutputFile: RegularFileProperty
@TaskAction
fun generatePluralRuleLists() {
val pluralRuleLists = parsePluralRuleLists()
val mainContent = generateMainContent(pluralRuleLists)
outputFile.get().asFile.writeText(mainContent)
val testContent = generateTestContent(pluralRuleLists)
samplesOutputFile.get().asFile.writeText(testContent)
}
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 ->
val rule = pluralRule.text().split('@')
PluralRule(
pluralRule.attribute("count").toString(),
// trim samples as not needed
rule[0].trim(),
rule.firstOrNull { it.startsWith("integer") }?.substringAfter("integer")?.trim() ?: "",
rule.firstOrNull { it.startsWith("decimal") }?.substringAfter("decimal")?.trim() ?: "",
)
}
)
}
}
private fun generateMainContent(pluralRuleLists: List<PluralRuleList>): String {
val pluralRuleListIndexByLocale = pluralRuleLists.flatMapIndexed { idx, pluralRuleList ->
pluralRuleList.locales.map { locale ->
locale to idx
}
}
return """
package org.jetbrains.compose.resources.plural
/**
* THIS CODE IS AUTOGENERATED BY './gradlew :resources:library:generatePluralRuleLists'
* DO NOT EDIT!!!
*/
internal val cldrPluralRuleListIndexByLocale = mapOf(
${pluralRuleListIndexByLocale.joinToString(separator = ",\n ") { (locale, idx) ->
"\"$locale\" to $idx"
}}
)
internal val cldrPluralRuleLists = arrayOf(${pluralRuleLists.joinToString(",") { pluralRuleList ->
"""
arrayOf(
${pluralRuleList.rules.joinToString(",\n ") { rule ->
"PluralCategory.${rule.count.uppercase()} to \"${rule.rule}\""
}}
)"""
}}
)
""".trimIndent()
}
private fun generateTestContent(pluralRuleLists: List<PluralRuleList>): String {
val pluralRuleIntegerSamplesByLocale = pluralRuleLists.flatMap { pluralRuleList ->
pluralRuleList.locales.map { locale ->
locale to pluralRuleList.rules.map { it.count to it.integerSample }
}
}
return """
package org.jetbrains.compose.resources.plural
/**
* THIS CODE IS AUTOGENERATED BY './gradlew :resources:library:generatePluralRuleLists'
* DO NOT EDIT!!!
*/
internal val cldrPluralRuleIntegerSamples = arrayOf(
${pluralRuleIntegerSamplesByLocale.joinToString(",\n ") { (locale, samples) ->
""""$locale" to arrayOf(
${samples.joinToString(",\n ") { (count, sample) ->
"PluralCategory.${count.uppercase()} to \"$sample\""
}}
)"""
}}
)
""".trimIndent()
}
}
private data class PluralRuleList(
val locales: List<String>,
val rules: List<PluralRule>,
)
private data class PluralRule(
val count: String,
val rule: String,
val integerSample: String,
val decimalSample: String,
)