diff --git a/app/src/main/kotlin/de/justjanne/quasseldroid/util/extensions/TextFormatterExtensions.kt b/app/src/main/kotlin/de/justjanne/quasseldroid/util/extensions/TextFormatterExtensions.kt new file mode 100644 index 0000000000000000000000000000000000000000..eeaba8ac3de4b902b643de39376415839baf9766 --- /dev/null +++ b/app/src/main/kotlin/de/justjanne/quasseldroid/util/extensions/TextFormatterExtensions.kt @@ -0,0 +1,25 @@ +package de.justjanne.quasseldroid.util.extensions + +import android.text.Spanned +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.buildAnnotatedString +import androidx.core.text.buildSpannedString +import de.justjanne.quasseldroid.util.AnnotatedStringAppender +import de.justjanne.quasseldroid.util.format.TextFormatter +import java.util.* + +fun TextFormatter.format( + template: AnnotatedString, + vararg args: Any?, + locale: Locale = Locale.getDefault() +): AnnotatedString = buildAnnotatedString { + formatBlocks(AnnotatedStringAppender(this), parseBlocks(template), args, locale) +} + +fun TextFormatter.format( + template: Spanned, + vararg args: Any?, + locale: Locale = Locale.getDefault() +): Spanned = buildSpannedString { + formatBlocks(this, parseBlocks(template), args, locale) +} diff --git a/app/src/main/kotlin/de/justjanne/quasseldroid/util/format/TextFormatter.kt b/app/src/main/kotlin/de/justjanne/quasseldroid/util/format/TextFormatter.kt index 3d605faa9253633e69852f8b60b85ebec3cf0384..858f258f8f81954ec97c009f995678cfc1963de8 100644 --- a/app/src/main/kotlin/de/justjanne/quasseldroid/util/format/TextFormatter.kt +++ b/app/src/main/kotlin/de/justjanne/quasseldroid/util/format/TextFormatter.kt @@ -16,38 +16,12 @@ package de.justjanne.quasseldroid.util.format -import android.text.Spanned -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.buildAnnotatedString -import androidx.core.text.buildSpannedString -import de.justjanne.quasseldroid.util.AnnotatedStringAppender import de.justjanne.quasseldroid.util.extensions.component6 import de.justjanne.quasseldroid.util.extensions.component7 import java.util.* import java.util.regex.Pattern -/** - * Provides [String.format] style functions that work with [Spanned] strings and preserve formatting. - * - * @author George T. Steel - */ object TextFormatter { - fun format( - template: AnnotatedString, - vararg args: Any?, - locale: Locale = Locale.getDefault() - ): AnnotatedString = buildAnnotatedString { - formatBlocks(AnnotatedStringAppender(this), parseBlocks(template), args, locale) - } - - fun format( - template: Spanned, - vararg args: Any?, - locale: Locale = Locale.getDefault() - ): Spanned = buildSpannedString { - formatBlocks(this, parseBlocks(template), args, locale) - } - fun format( template: String, vararg args: Any?, @@ -56,7 +30,7 @@ object TextFormatter { formatBlocks(this, parseBlocks(template), args, locale) } - internal fun formatBlocks( + fun formatBlocks( target: Appendable, blocks: Sequence<FormatString>, args: Array<out Any?>, @@ -67,10 +41,14 @@ object TextFormatter { when (block) { is FormatString.FixedValue -> target.append(block.content) is FormatString.FormatSpecifier -> { - val arg = when { - block.argumentIndex != null -> args[block.argumentIndex - 1] - block.flags.orEmpty().contains(FLAG_REUSE_ARGUMENT) -> args[argIndex] - else -> args[argIndex++] + val index = when { + block.argumentIndex != null -> block.argumentIndex - 1 + block.flags.orEmpty().contains(FLAG_REUSE_ARGUMENT) -> argIndex + else -> argIndex++ + } + val arg = if (index in 0..args.size) args[index] else { + target.append(block.toFormatSpecifier()) + continue } if (block.conversion.lowercaseChar() == TYPE_STRING) { @@ -109,7 +87,7 @@ object TextFormatter { } } - internal fun parseBlocks(template: CharSequence) = sequence { + fun parseBlocks(template: CharSequence) = sequence { var index = 0 while (index < template.length) { val match = FORMAT_SEQUENCE.toRegex().find(template, index)