@@ -7,7 +7,7 @@ import java.util.EnumSet
77/* *
88 * Coverts string with "§" to a [TextComponent].
99 */
10- internal fun String.toTextComponent (): TextComponent {
10+ fun String.toTextComponent (): TextComponent {
1111 val components = mutableListOf<TextComponent >()
1212 var currentText = StringBuilder ()
1313 var currentColor = " "
@@ -21,22 +21,20 @@ internal fun String.toTextComponent(): TextComponent {
2121
2222 if (currentText.isNotEmpty()) {
2323 components + = TextComponent (
24- text = currentText.toString(),
25- color = currentColor,
26- styles = EnumSet .copyOf(currentStyles)
24+ text = currentText.toString(), color = currentColor, styles = EnumSet .copyOf(currentStyles)
2725 )
2826 currentText = StringBuilder ()
2927 }
3028
31- // §r 重置
29+ // §r reset
3230 if (code == ' r' ) {
3331 currentColor = " "
3432 currentStyles.clear()
3533 } else {
36- // §0-§f 颜色
37- colorMap [code]?.let { currentColor = it }
38- // §k-§o 样式
39- styleMap [code]?.let { currentStyles + = it }
34+ // §0-§f colors
35+ originalColorMap [code]?.let { currentColor = it }
36+ // §k-§o styles
37+ originalStyleMap [code]?.let { currentStyles + = it }
4038 }
4139 } else {
4240 currentText.append(c)
@@ -45,35 +43,78 @@ internal fun String.toTextComponent(): TextComponent {
4543
4644 if (currentText.isNotEmpty()) {
4745 components + = TextComponent (
48- text = currentText.toString(),
49- color = currentColor,
50- styles = EnumSet .copyOf(currentStyles)
46+ text = currentText.toString(), color = currentColor, styles = EnumSet .copyOf(currentStyles)
5147 )
5248 }
5349
5450 return if (components.size == 1 ) {
5551 components[0 ]
5652 } else {
5753 TextComponent (
58- text = " " ,
59- color = " " ,
60- styles = EnumSet .noneOf(TextStyle ::class .java),
61- extra = components
54+ text = " " , color = " " , styles = EnumSet .noneOf(TextStyle ::class .java), extra = components
6255 )
6356 }
6457}
6558
66- private val colorMap = mapOf (
67- ' 0' to " #000000" , ' 1' to " #0000AA" , ' 2' to " #00AA00" , ' 3' to " #00AAAA" ,
68- ' 4' to " #AA0000" , ' 5' to " #AA00AA" , ' 6' to " #FFAA00" , ' 7' to " #AAAAAA" ,
69- ' 8' to " #555555" , ' 9' to " #5555FF" , ' a' to " #55FF55" , ' b' to " #55FFFF" ,
70- ' c' to " #FF5555" , ' d' to " #FF55FF" , ' e' to " #FFFF55" , ' f' to " #FFFFFF"
59+ private val originalColorMap = mapOf (
60+ ' 0' to " #000000" ,
61+ ' 1' to " #0000AA" ,
62+ ' 2' to " #00AA00" ,
63+ ' 3' to " #00AAAA" ,
64+ ' 4' to " #AA0000" ,
65+ ' 5' to " #AA00AA" ,
66+ ' 6' to " #FFAA00" ,
67+ ' 7' to " #AAAAAA" ,
68+ ' 8' to " #555555" ,
69+ ' 9' to " #5555FF" ,
70+ ' a' to " #55FF55" ,
71+ ' b' to " #55FFFF" ,
72+ ' c' to " #FF5555" ,
73+ ' d' to " #FF55FF" ,
74+ ' e' to " #FFFF55" ,
75+ ' f' to " #FFFFFF"
7176)
7277
73- private val styleMap = mapOf (
78+ private val originalStyleMap = mapOf (
7479 ' l' to TextStyle .BOLD ,
7580 ' o' to TextStyle .ITALIC ,
7681 ' n' to TextStyle .UNDERLINED ,
7782 ' m' to TextStyle .STRIKETHROUGH ,
7883 ' k' to TextStyle .OBFUSCATED
7984)
85+
86+ /* *
87+ * Converts [TextComponent] to a HTML element.
88+ */
89+ fun TextComponent.toHtml (): String {
90+ var html = escapeHtml(text).replace(" " , " " ).replace(" \n " , " <br />" )
91+
92+ if (extra.isNotEmpty()) {
93+ html + = extra.joinToString(" " ) { it.toHtml() }
94+ }
95+
96+ if (TextStyle .OBFUSCATED in styles) html = """ <span class="obfuscated">$html </span>"""
97+ if (TextStyle .STRIKETHROUGH in styles) html = " <s>$html </s>"
98+ if (TextStyle .UNDERLINED in styles) html = " <u>$html </u>"
99+ if (TextStyle .ITALIC in styles) html = " <i>$html </i>"
100+ if (TextStyle .BOLD in styles) html = " <b>$html </b>"
101+
102+ return if (color.isNotEmpty()) {
103+ """ <span style="color:$color ">$html </span>"""
104+ } else {
105+ html
106+ }
107+ }
108+
109+ private fun escapeHtml (text : String ): String = buildString {
110+ for (c in text) {
111+ when (c) {
112+ ' <' -> append(" <" )
113+ ' >' -> append(" >" )
114+ ' &' -> append(" &" )
115+ ' "' -> append(" "" )
116+ ' \' ' -> append(" '" )
117+ else -> append(c)
118+ }
119+ }
120+ }
0 commit comments