Skip to content

Commit

Permalink
Add option on the xml processor to avoid creating compose accessors (#46
Browse files Browse the repository at this point in the history
)
  • Loading branch information
prof18 committed Apr 5, 2024
1 parent a75cba8 commit 7b17b95
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 30 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ Let's say you have a "dashboard" module, the generated declarations will be `Loc

## Migrating from `strings.xml`
So you liked Lyricist, but already have a project with thousands of strings spread over multiples files? I have good news for you: Lyricist can extract these existing strings and generate all the code you just saw above.
If you don't want to have the Compose code generated by KSP, you can set the `lyricist.xml.generateComposeAccessors` arg to `"false"`, and you can write the code manually by following the instructions [below](#extending-lyricist).

Similar to the multi module setup, you must provide a few arguments to KSP. Lyricist will search for `strings.xml` files in the resources path. You can also provide a language tag to be used as default value for the `LocalStrings`.
```gradle
Expand All @@ -192,6 +193,7 @@ ksp {
arg("lyricist.packageName", "com.my.app")
arg("lyricist.xml.moduleName", "xml")
arg("lyricist.xml.defaultLanguageTag", "en")
arg("lyricist.xml.generateComposeAccessors", "false")
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ internal data class LyricistXmlConfig(
val moduleName: String,
val defaultLanguageTag: String,
val resourcesPath: String,
val generateComposeAccessors: Boolean,
)
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,26 @@ internal class LyricistXmlSymbolProcessor(
"""
|package ${config.packageName}
|
|import androidx.compose.runtime.Composable
|import androidx.compose.runtime.ProvidableCompositionLocal
|import androidx.compose.runtime.staticCompositionLocalOf
|import androidx.compose.ui.text.intl.Locale
|import cafe.adriel.lyricist.Lyricist
|import cafe.adriel.lyricist.LanguageTag
|import cafe.adriel.lyricist.rememberStrings
|import cafe.adriel.lyricist.ProvideStrings
""".trimMargin().toByteArray()
)
if (config.generateComposeAccessors) {
stream.write(
"""
|
|import androidx.compose.runtime.Composable
|import androidx.compose.runtime.ProvidableCompositionLocal
|import androidx.compose.runtime.staticCompositionLocalOf
|import androidx.compose.ui.text.intl.Locale
|import cafe.adriel.lyricist.Lyricist
|import cafe.adriel.lyricist.LanguageTag
|import cafe.adriel.lyricist.rememberStrings
|import cafe.adriel.lyricist.ProvideStrings
|
""".trimMargin().toByteArray()
)
}
stream.write(
"""
|
|public interface $fileName {
|$values
Expand All @@ -126,29 +138,36 @@ internal class LyricistXmlSymbolProcessor(
|$localesOutput
|}
|
|public val $stringsName: Map<LanguageTag, $fileName> = mapOf(
|$translationMappingOutput
|)
|
|public val Local$fileName: ProvidableCompositionLocal<$fileName> =
| staticCompositionLocalOf { $defaultStringsOutput }
|
|@Composable
|public fun remember$fileName(
| defaultLanguageTag: LanguageTag = "${config.defaultLanguageTag}",
| currentLanguageTag: LanguageTag = Locale.current.toLanguageTag(),
|): Lyricist<$fileName> =
| rememberStrings($stringsName, defaultLanguageTag, currentLanguageTag)
|
|@Composable
|public fun Provide$fileName(
| lyricist: Lyricist<$fileName>,
| content: @Composable () -> Unit
|) {
| ProvideStrings(lyricist, Local$fileName, content)
|}
""".trimMargin().toByteArray()
)
if (config.generateComposeAccessors) {
stream.write(
"""
|
|public val $stringsName: Map<LanguageTag, $fileName> = mapOf(
|$translationMappingOutput
|)
|
|public val Local$fileName: ProvidableCompositionLocal<$fileName> =
| staticCompositionLocalOf { $defaultStringsOutput }
|
|@Composable
|public fun remember$fileName(
| defaultLanguageTag: LanguageTag = "${config.defaultLanguageTag}",
| currentLanguageTag: LanguageTag = Locale.current.toLanguageTag(),
|): Lyricist<$fileName> =
| rememberStrings($stringsName, defaultLanguageTag, currentLanguageTag)
|
|@Composable
|public fun Provide$fileName(
| lyricist: Lyricist<$fileName>,
| content: @Composable () -> Unit
|) {
| ProvideStrings(lyricist, Local$fileName, content)
|}
""".trimMargin().toByteArray()
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ internal class LyricistXmlSymbolProcessorProvider : SymbolProcessorProvider {
moduleName = options[ARG_MODULE_NAME].orEmpty(),
defaultLanguageTag = options[ARG_DEFAULT_LANGUAGE_TAG] ?: DEFAULT_LANGUAGE_TAG,
resourcesPath = options[ARG_RESOURCES_PATH]
?: throw IllegalArgumentException("lyricist.xml.resourcesPath not found")
?: throw IllegalArgumentException("lyricist.xml.resourcesPath not found"),
generateComposeAccessors = options[ARG_GENERATE_COMPOSE_ACCESSORS]?.toBoolean() ?: true
),
codeGenerator = codeGenerator,
logger = logger
Expand All @@ -26,6 +27,7 @@ internal class LyricistXmlSymbolProcessorProvider : SymbolProcessorProvider {
const val ARG_MODULE_NAME = "lyricist.xml.moduleName"
const val ARG_RESOURCES_PATH = "lyricist.xml.resourcesPath"
const val ARG_DEFAULT_LANGUAGE_TAG = "lyricist.xml.defaultLanguageTag"
const val ARG_GENERATE_COMPOSE_ACCESSORS = "lyricist.xml.generateComposeAccessors"

const val DEFAULT_PACKAGE_NAME = "cafe.adriel.lyricist"
const val DEFAULT_LANGUAGE_TAG = "en"
Expand Down

0 comments on commit 7b17b95

Please sign in to comment.