Skip to content

Commit a38d802

Browse files
authored
Merge pull request #181 from Q42/feature/color-parser-script
ADD color parser script
2 parents 0d2a10e + ce30f6a commit a38d802

4 files changed

Lines changed: 158 additions & 0 deletions

File tree

README.MD

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ Using Bitrise or another CI tool instead? Then you can skip the above and delete
142142

143143
- `./.github/workflows`
144144

145+
### Colors import from Figma
146+
147+
This project contains a script to convert color tokens from Figma to Compose format.
148+
You can find the script and instructions in the `./scripts/colorparser/README.md` file.
149+
145150
## Setup decisions
146151

147152
### Clean architecture
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/usr/bin/env kotlin
2+
3+
import java.io.File
4+
import java.io.FileWriter
5+
6+
/**
7+
* Check README.md for info about this script.
8+
*
9+
* This script might need a few adjustments per project, based on the figma setup. At
10+
* the very least, update the app name below.
11+
*/
12+
13+
val appName = "template"
14+
15+
val themePackage = "nl.q42.$appName.ui.theme"
16+
val outputPath = "../../core/ui/src/main/kotlin/nl/q42/$appName/ui/theme"
17+
val inputFile = File("color_parser_input.kt")
18+
19+
data class ThemeWriter(
20+
val classSuffix: String,
21+
val inputColorNameSuffix: String,
22+
val writer: FileWriter = FileWriter(File("$outputPath/AppColorScheme$classSuffix.kt"))
23+
)
24+
25+
val themeWriters = listOf(
26+
ThemeWriter(
27+
classSuffix = "Light",
28+
inputColorNameSuffix = "_light",
29+
),
30+
ThemeWriter(
31+
classSuffix = "Dark",
32+
inputColorNameSuffix = "_dark",
33+
)
34+
)
35+
36+
val colorAssignmentPattern = " = Color\\(0x[0-9a-fA-F]{8}\\)".toRegex()
37+
38+
fun FileWriter.appendInterfaceFieldLineIfMatches(inputLine: String, inputColorNameSuffix: String) {
39+
if (inputLine.trim().endsWith(inputColorNameSuffix)) {
40+
appendLine(
41+
" " + inputLine.replace(inputColorNameSuffix, "")
42+
.replace(colorAssignmentPattern, ": Color")
43+
)
44+
}
45+
}
46+
47+
fun ThemeWriter.appendLineIfMatches(line: String) {
48+
if (line.trim().endsWith(inputColorNameSuffix)) {
49+
writer.append(" override ") // Indentation + override keyword
50+
writer.appendLine(line.replace(inputColorNameSuffix, ""))
51+
}
52+
}
53+
54+
fun ThemeWriter.writeAppColorsHeader() {
55+
writer.appendLine(
56+
"""
57+
package ${themePackage}
58+
59+
import androidx.compose.ui.graphics.Color
60+
import ${themePackage}.AppColorScheme
61+
62+
/**
63+
* GENERATED FILE: Do not edit this file manually.
64+
* See [scripts/colorparser/ColorParser.kts] for more information.
65+
*/
66+
object AppColorScheme$classSuffix : AppColorScheme {
67+
""".trimIndent()
68+
)
69+
}
70+
71+
fun FileWriter.writeBlockClose() {
72+
appendLine("}")
73+
appendLine() // Empty last line
74+
}
75+
76+
fun ThemeWriter.writeAppColorsFooter() {
77+
writer.writeBlockClose()
78+
}
79+
80+
fun FileWriter.writeAppColorsInterface() {
81+
appendLine(
82+
"""
83+
package ${themePackage}
84+
85+
import androidx.compose.ui.graphics.Color
86+
87+
/**
88+
* GENERATED FILE: Do not edit this file manually.
89+
* See [scripts/colorparser/ColorParser.kts] for more information.
90+
*/
91+
interface AppColorScheme {
92+
""".trimIndent()
93+
)
94+
95+
val inputColorNameSuffix = themeWriters.first().inputColorNameSuffix
96+
inputFile.forEachLine { inputLine ->
97+
appendInterfaceFieldLineIfMatches(inputLine, inputColorNameSuffix)
98+
}
99+
100+
writeBlockClose()
101+
}
102+
103+
// Write interface
104+
FileWriter(File("$outputPath/AppColorScheme.kt")).use {
105+
it.writeAppColorsInterface()
106+
}
107+
108+
// Write themes
109+
themeWriters.forEach { themeWriter ->
110+
with(themeWriter) {
111+
writeAppColorsHeader()
112+
inputFile.forEachLine { inputLine ->
113+
appendLineIfMatches(inputLine)
114+
}
115+
writeAppColorsFooter()
116+
writer.close()
117+
}
118+
}

scripts/colorparser/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Color Parser
2+
3+
This script converts color tokens from Figma to Compose format. It is designed to be used with the
4+
figma 'Color2Code' plugin, which exports the Color Tokens.
5+
6+
## Requirements
7+
8+
- Android Studio
9+
- 'Color2Code' plugin for Figma
10+
- command line kotlin (`brew install kotlin`)
11+
12+
## Usage
13+
14+
1. Open
15+
the [Color Tokens page](https://www.figma.com/file/jTFWg6tZjCWwcxqwkKmykZ/app-foundation?type=design&node-id=1259-12&mode=design&t=BcdgPKHmtGLKMZL8-11)
16+
in Figma.
17+
1. Run the [Color2Code](https://www.figma.com/community/plugin/1262830857362718014) plugin in Figma.
18+
Note: you need edit rights for this, perhaps you need to do
19+
this in collaboration with a designer.
20+
2. Export the Color Tokens using the plugin. Disable `Remove group names`; enable
21+
`Camel case naming` select `Android` and `Semantics`.
22+
![Color 2 Code settings](color_parser_color_2_code.png)
23+
3. Copy the output of the plugin and paste it into the `color_parser_input.txt` file.
24+
4. Run the `ColorParser.kts` script by clicking the play button in the file or running
25+
26+
`./scripts/colorparser/ColorParser.kts`
27+
28+
5. The script will update the `AppColorScheme.kt` file and the corresponding files for both the
29+
light and dark themes.
30+
31+
## File Structure
32+
33+
- `color_parser_input.kt`: Paste the output of the 'Color2Code' plugin here.
34+
- `ColorParser.kts`: Script to parse the color tokens and generate the Compose code.
35+
`

scripts/colorparser/color_parser_input.kt

Whitespace-only changes.

0 commit comments

Comments
 (0)