Skip to content

Commit

Permalink
♻️ style:
Browse files Browse the repository at this point in the history
1. typo
2. use companion object
3. more functional style
  • Loading branch information
Jian-Min-Huang committed Nov 21, 2022
1 parent c437d68 commit 6b1a13e
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 124 deletions.
6 changes: 3 additions & 3 deletions README.md
@@ -1,6 +1,6 @@
# emoji-jvm-string 👺

> Let's access emoji like Enum and print it easily 😎
> Let's access emoji like Enum and print it easily. 😎
## Sample Code 📜

Expand Down Expand Up @@ -70,5 +70,5 @@ dependencies {
```

## Issue
Q: Why not just one Emoji class ?
> All enum in one .kt is will exceed jvm limit 64K.
Q: Why not just one Emoji class?
> All enum in one .kt will exceed jvm limit 64K.
10 changes: 6 additions & 4 deletions src/main/kotlin/net/purefunc/generate/Main.kt
@@ -1,11 +1,13 @@
package net.purefunc.generate

import net.purefunc.generate.util.EmojiCollector
import net.purefunc.generate.util.EmojiFileCreator
import net.purefunc.generate.util.EmojiReader
import net.purefunc.generate.util.ValidEmojiCollector

fun main() {
val roughList = EmojiReader("https://unicode.org/Public/emoji/15.0/emoji-test.txt").readTargetUrl()
val bigEnum = ValidEmojiCollector(roughList).filter()
EmojiFileCreator(1000).writeAsEnumFile(bigEnum)
EmojiFileCreator.writeAsEnumFile(
EmojiCollector.filter(
EmojiReader.readTargetUrl("https://unicode.org/Public/emoji/15.0/emoji-test.txt")
)
)
}
50 changes: 50 additions & 0 deletions src/main/kotlin/net/purefunc/generate/util/EmojiCollector.kt
@@ -0,0 +1,50 @@
package net.purefunc.generate.util

class EmojiCollector {

companion object {
fun filter(source: List<String>) =
source
.filter {
it.contains("fully-qualified")
}.map {
it.split(" ")
}.map { elements ->
// [1F636, 200D, 1F32B, FE0F, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ;, fully-qualified, , , , , #, 😶‍🌫️, E13.1, face, in, cloud]

val items = mutableListOf<String>()

val codePartIdxs = elements.mapIndexed { idx, element -> if (element.isEmpty() || element == ";") idx else -1 }
val codeIdx = codePartIdxs.first { idx -> idx != -1 }

(0 until codeIdx).forEach { i -> items.add(elements[i]) }
items.add(";")

val namePartIdxs =
elements.mapIndexed { idx, element -> if (element.startsWith("E") && element.contains(".")) idx else -1 }
val nameIdx = namePartIdxs.first { idx -> idx != -1 }

items.plus(elements.subList(nameIdx + 1, elements.size).map { str -> convertToValidChar(str) })
}

private fun convertToValidChar(str: String) =
// replace item name contains invalid char
str.replace("", "")
.replace("", "")
.replace("", "")
.replace("-", "_")
.replace(":", "")
.replace(".", "")
.replace("!", "")
.replace("(", "")
.replace(")", "")
.replace("1st", "first")
.replace("2nd", "second")
.replace("3rd", "third")
.replace("package", "packages")
.replace("#", "hash")
.replace("*", "star")
.replace(",", "comma")
.replace("&", "and")
}
}
108 changes: 54 additions & 54 deletions src/main/kotlin/net/purefunc/generate/util/EmojiFileCreator.kt
Expand Up @@ -2,76 +2,76 @@ package net.purefunc.generate.util

import java.io.File
import java.io.FileOutputStream
import java.util.*

class EmojiFileCreator(private val pageCount: Int) {
// all enum in one .kt is will exceed jvm limit 64K
fun writeAsEnumFile(source: List<List<String>>): Unit {
val pagingItems = allocatePerPageItem(source)

pagingItems.forEachIndexed { fileIdx, item ->
val fos = FileOutputStream(File("src/main/kotlin/net/purefunc/emoji/Emoji$fileIdx.kt"))
fos.generateFileHeader(fileIdx)

item.forEachIndexed { idx, element ->
val idxListThird = element.mapIndexed { i, e -> if (e == ";") i else -1 }
val splitIdx = idxListThird.first { i -> i != -1 }

val name = element.subList(splitIdx + 1, element.size).joinToString("_").uppercase(Locale.getDefault())
val hexs = element.subList(0, splitIdx).joinToString(",") { hex -> "0x$hex" }
val emojiIntArr = element.subList(0, splitIdx).map { hex -> hex.toInt(16) }.toIntArray()
val emoji = String(emojiIntArr, 0, emojiIntArr.size)

val comment = " // $emoji $emoji $emoji"
val enum = " $name(intArrayOf($hexs))"
if (idx == item.size - 1) {
fos.writeLastLine(comment, enum)
} else {
fos.writeNextLine(comment, enum)
import java.util.Locale

class EmojiFileCreator {

companion object {
// all enum in one .kt will exceed jvm limit 64K
fun writeAsEnumFile(source: List<List<String>>, pageCount: Int = 1000) {
val pagingItems = allocatePerPageItem(source, pageCount)

pagingItems.forEachIndexed { fileIdx, item ->
val fos = FileOutputStream(File("src/main/kotlin/net/purefunc/emoji/Emoji$fileIdx.kt"))
fos.generateFileHeader(fileIdx)

item.forEachIndexed { idx, element ->
val idxListThird = element.mapIndexed { i, e -> if (e == ";") i else -1 }
val splitIdx = idxListThird.first { i -> i != -1 }

val name = element.subList(splitIdx + 1, element.size).joinToString("_").uppercase(Locale.getDefault())
val hexs = element.subList(0, splitIdx).joinToString(",") { hex -> "0x$hex" }
val emojiIntArr = element.subList(0, splitIdx).map { hex -> hex.toInt(16) }.toIntArray()
val emoji = String(emojiIntArr, 0, emojiIntArr.size)

val comment = " // $emoji $emoji $emoji"
val enum = " $name(intArrayOf($hexs))"
if (idx == item.size - 1) {
fos.writeLastLine(comment, enum)
} else {
fos.writeNextLine(comment, enum)
}
}
}

fos.generateFileFooter()
fos.generateFileFooter()
}
}
}

private fun allocatePerPageItem(source: List<List<String>>): List<List<List<String>>> {
val pageSize = (source.size / pageCount)
return (0..pageSize).map { page ->
val pageList: (Int) -> List<List<String>> = { source.subList(pageCount * page, it) }
if (pageCount * (page + 1) > source.size)
pageList(source.size)
else
pageList(pageCount * (page + 1))

private fun allocatePerPageItem(source: List<List<String>>, pageCount: Int): List<List<List<String>>> {
val pageSize = (source.size / pageCount)
return (0..pageSize).map { page ->
val pageList: (Int) -> List<List<String>> = { source.subList(pageCount * page, it) }
if (pageCount * (page + 1) > source.size)
pageList(source.size)
else
pageList(pageCount * (page + 1))
}
}
}

private fun FileOutputStream.generateFileHeader(fileIdx: Int) =
write(
"""
private fun FileOutputStream.generateFileHeader(fileIdx: Int) =
write(
"""
package net.purefunc.emoji
enum class Emoji$fileIdx(
private val intArray: IntArray,
) {
""".trimIndent().toByteArray()
)
)

private fun FileOutputStream.writeNextLine(comment: String, enum: String) = write("$comment\n$enum,\n".toByteArray())
private fun FileOutputStream.writeNextLine(comment: String, enum: String) = write("$comment\n$enum,\n".toByteArray())

private fun FileOutputStream.writeLastLine(comment: String, enum: String) = write("$comment\n$enum;\n".toByteArray())
private fun FileOutputStream.writeLastLine(comment: String, enum: String) = write("$comment\n$enum;\n".toByteArray())

private fun FileOutputStream.generateFileFooter() =
write(
"""
private fun FileOutputStream.generateFileFooter() =
write(
"""
override fun toString() = String(intArray, 0, intArray.size)
}
override fun toString() = String(intArray, 0, intArray.size)
}
""".trimIndent().toByteArray()
)

)
}
}
28 changes: 15 additions & 13 deletions src/main/kotlin/net/purefunc/generate/util/EmojiReader.kt
Expand Up @@ -4,20 +4,22 @@ import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.URL

class EmojiReader(private val targetUrl: String) {
class EmojiReader {

fun readTargetUrl(): List<String> =
// collect emoji lines
// 1F636 200D 1F32B FE0F ; fully-qualified # 😶‍🌫️ E13.1 face in clouds
buildList {
var flag = false
val reader = BufferedReader(InputStreamReader(URL(targetUrl).openConnection().getInputStream()))
reader.useLines { readLines ->
readLines.forEach { line ->
if (line.isEmpty()) flag = false
if (flag) add(line)
if (line.startsWith("# subgroup: ")) flag = true
companion object {
fun readTargetUrl(targetUrl: String): List<String> =
// collect emoji lines
// 1F636 200D 1F32B FE0F ; fully-qualified # 😶‍🌫️ E13.1 face in clouds
buildList {
var flag = false
val reader = BufferedReader(InputStreamReader(URL(targetUrl).openConnection().getInputStream()))
reader.useLines { readLines ->
readLines.forEach { line ->
if (line.isEmpty()) flag = false
if (flag) add(line)
if (line.startsWith("# subgroup: ")) flag = true
}
}
}
}
}
}
50 changes: 0 additions & 50 deletions src/main/kotlin/net/purefunc/generate/util/ValidEmojiCollector.kt

This file was deleted.

0 comments on commit 6b1a13e

Please sign in to comment.