Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle camelCase icon names, introduce IconNameFormatter #155

Merged
merged 1 commit into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.github.composegears.valkyrie.parser.svgxml

import io.github.composegears.valkyrie.parser.svgxml.util.capitalized
import io.github.composegears.valkyrie.parser.svgxml.util.removePrefix

object IconNameFormatter {

private val invalidCharacterRegex = "[^a-zA-Z0-9\\-_ ]".toRegex()
private val camelCaseRegex = "(?<!^)(?=[A-Z])|(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)".toRegex()

fun format(name: String): String = name
.trimStart('-', '_')
.removeSuffix(".svg")
.removeSuffix(".xml")
.removePrefix("ic_")
.removePrefix("ic-")
.replace(invalidCharacterRegex, "_")
.split(camelCaseRegex)
.joinToString(separator = "") { it.capitalized() }
.split("_", "-")
.joinToString(separator = "") { it.capitalized() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import io.github.composegears.valkyrie.parser.svgxml.svg.SvgToXmlParser
import io.github.composegears.valkyrie.parser.svgxml.util.IconType
import io.github.composegears.valkyrie.parser.svgxml.util.IconType.SVG
import io.github.composegears.valkyrie.parser.svgxml.util.IconType.XML
import io.github.composegears.valkyrie.parser.svgxml.util.capitalized
import io.github.composegears.valkyrie.parser.svgxml.util.removePrefix
import io.github.composegears.valkyrie.parser.svgxml.xml.XmlStringParser
import java.nio.file.Path
import kotlin.io.path.createTempFile
Expand All @@ -25,7 +23,7 @@ object SvgXmlParser {
fun toIrImageVector(path: Path): IconParserOutput {
val iconType = IconType.from(path.extension) ?: error("File not SVG or XML")

val fileName = getIconName(fileName = path.name)
val fileName = IconNameFormatter.format(name = path.name)
val text = when (iconType) {
SVG -> {
val tmpPath = createTempFile(suffix = "valkyrie/")
Expand All @@ -40,16 +38,4 @@ object SvgXmlParser {
kotlinName = fileName,
)
}

// TODO: extract into separate class
fun getIconName(fileName: String) = fileName
.removePrefix("-")
.removePrefix("_")
.removeSuffix(".svg")
.removeSuffix(".xml")
.removePrefix("ic_")
.removePrefix("ic-")
.replace("[^a-zA-Z0-9\\-_ ]".toRegex(), "_")
.split("_", "-")
.joinToString(separator = "") { it.lowercase().capitalized() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,45 @@ import assertk.assertThat
import assertk.assertions.isEqualTo
import org.junit.jupiter.api.Test

class XmlStringParserTest {
class IconNameFormatterTest {

private data class IconTest(
val fileName: String,
val expected: String,
)

@Test
fun `test icon name`() {
fun `check icon name formatting`() {
val fileNames = listOf(
IconTest(fileName = "_ic_test_icon.svg", expected = "TestIcon"),
IconTest(fileName = "ic_test_icon.svg", expected = "TestIcon"),
IconTest(fileName = "ic_test_icon.xml", expected = "TestIcon"),
IconTest(fileName = "test_icon.svg", expected = "TestIcon"),
IconTest(fileName = "ic_test_icon2.svg", expected = "TestIcon2"),
IconTest(fileName = "ic_test_icon_name.svg", expected = "TestIconName"),
IconTest(fileName = "ic_testicon.svg", expected = "Testicon"),
IconTest(fileName = "ic_test_icon_name_with_underscores.svg", expected = "TestIconNameWithUnderscores"),
IconTest(fileName = "ic_TESTIcon.svg", expected = "Testicon"),
IconTest(fileName = "ic_SVGIcon.svg", expected = "SVGIcon"),
IconTest(fileName = "ic-test-icon.svg", expected = "TestIcon"),
IconTest(fileName = "ic_test@icon!.svg", expected = "TestIcon"),
IconTest(fileName = "ic_test_icon123.xml", expected = "TestIcon123"),
IconTest(fileName = "my_icon.xml", expected = "MyIcon"),
IconTest(fileName = "Ic_TeSt123Icon.svg", expected = "Test123icon"),
IconTest(fileName = "Ic_TeSt123Icon.svg", expected = "TeSt123Icon"),
IconTest(fileName = "ic_special@#\$%^&*()icon.svg", expected = "SpecialIcon"),
IconTest(fileName = "ic--test__icon---name.svg", expected = "TestIconName"),
IconTest(fileName = "@#$%.svg", expected = ""),
IconTest(fileName = "", expected = ""),
IconTest(fileName = "-_ic_test_icon_-.svg", expected = "TestIcon"),
IconTest(fileName = "pos_1", expected = "Pos1"),
IconTest(fileName = "1", expected = "1"),
IconTest(fileName = "Ic_TempSvg123Icon.svg", expected = "TempSvg123Icon"),
IconTest(fileName = "fitContent", expected = "FitContent"),
IconTest(fileName = "fitContent_dark", expected = "FitContentDark"),
IconTest(fileName = "stub@20x20", expected = "Stub20X20"),
)

fileNames.forEach {
val iconName = SvgXmlParser.getIconName(it.fileName)
val iconName = IconNameFormatter.format(it.fileName)

assertThat(iconName).isEqualTo(it.expected)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import io.github.composegears.valkyrie.extensions.cast
import io.github.composegears.valkyrie.generator.imagevector.ImageVectorGenerator
import io.github.composegears.valkyrie.generator.imagevector.ImageVectorGeneratorConfig
import io.github.composegears.valkyrie.generator.imagevector.ImageVectorSpecOutput
import io.github.composegears.valkyrie.parser.svgxml.IconNameFormatter
import io.github.composegears.valkyrie.parser.svgxml.SvgXmlParser
import io.github.composegears.valkyrie.parser.svgxml.util.isSvg
import io.github.composegears.valkyrie.parser.svgxml.util.isXml
Expand Down Expand Up @@ -237,7 +238,7 @@ class IconPackConversionViewModel(
extension = path.extension,
)
else -> BatchIcon.Valid(
iconName = IconName(SvgXmlParser.getIconName(path.name)),
iconName = IconName(IconNameFormatter.format(path.name)),
extension = path.extension,
iconPack = inMemorySettings.current.buildDefaultIconPack(),
path = path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp
import io.github.composegears.valkyrie.parser.svgxml.SvgXmlParser
import io.github.composegears.valkyrie.parser.svgxml.IconNameFormatter
import io.github.composegears.valkyrie.ui.foundation.IconButton
import io.github.composegears.valkyrie.ui.foundation.icons.ValkyrieIcons
import io.github.composegears.valkyrie.ui.foundation.icons.Visibility
Expand Down Expand Up @@ -308,7 +308,7 @@ private fun BatchProcessingStatePreview() = PreviewTheme {
exportEnabled = false,
icons = listOf(
BatchIcon.Valid(
iconName = IconName(SvgXmlParser.getIconName("ic_all_path_params_1")),
iconName = IconName(IconNameFormatter.format("ic_all_path_params_1")),
extension = "xml",
path = Path(""),
iconPack = IconPack.Single(
Expand All @@ -321,7 +321,7 @@ private fun BatchProcessingStatePreview() = PreviewTheme {
extension = "svg",
),
BatchIcon.Valid(
iconName = IconName(SvgXmlParser.getIconName("ic_all_path")),
iconName = IconName(IconNameFormatter.format("ic_all_path")),
extension = "svg",
path = Path(""),
iconPack = IconPack.Nested(
Expand Down