6.6.1 - Alpha2 - 支持 Node.js 拼音模块及结巴分词
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package org.autojs.autojs.engine
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import org.autojs.autojs.core.ui.ViewExtras
|
||||
@@ -179,7 +180,16 @@ open class RhinoJavaScriptEngine(private val scriptRuntime: ScriptRuntime, priva
|
||||
initStandardObjects(context, false)
|
||||
}
|
||||
|
||||
fun enterContext(): Context = RhinoAndroidHelper(androidContext).enterContext().also { setupContext(it) }
|
||||
@SuppressLint("VisibleForTests")
|
||||
fun enterContext(): Context {
|
||||
val rhinoAndroidHelper = RhinoAndroidHelper(androidContext)
|
||||
val enterContext = try {
|
||||
rhinoAndroidHelper.enterContext()
|
||||
} catch (e: SecurityException) {
|
||||
rhinoAndroidHelper.contextFactory.enterContext()
|
||||
}
|
||||
return enterContext.also { setupContext(it) }
|
||||
}
|
||||
|
||||
fun setupContext(context: Context) = context.apply {
|
||||
if (this is AutoJsContext) {
|
||||
|
||||
@@ -72,6 +72,7 @@ import org.autojs.autojs.runtime.api.augment.ocr.OcrPaddle
|
||||
import org.autojs.autojs.runtime.api.augment.ocr.OcrRapid
|
||||
import org.autojs.autojs.runtime.api.augment.opencc.OpenCC
|
||||
import org.autojs.autojs.runtime.api.augment.pinyin.Pinyin
|
||||
import org.autojs.autojs.runtime.api.augment.pinyin4j.Pinyin4j
|
||||
import org.autojs.autojs.runtime.api.augment.plugins.Plugins
|
||||
import org.autojs.autojs.runtime.api.augment.recorder.Recorder
|
||||
import org.autojs.autojs.runtime.api.augment.s13n.S13n
|
||||
@@ -763,6 +764,7 @@ class ScriptRuntime private constructor(builder: Builder) {
|
||||
SQLite(this).augment(target, true)
|
||||
NanoID.augment(target, true)
|
||||
Pinyin.augment(target, true)
|
||||
Pinyin4j.augment(target, true)
|
||||
|
||||
augmentedApp.defineProp(Autojs::class.java.simpleName.lowercase(), augmentedAutojs)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class RootAutomatorNativeObject(scriptRuntime: ScriptRuntime, waitForReady: Any?
|
||||
|
||||
init {
|
||||
super.exportAsJSClass(MAX_PROTOTYPE_ID, this, false)
|
||||
defineProperty("__ra__", mRootAutomatorObject, DONTENUM or READONLY or PERMANENT)
|
||||
defineProperty("__ra__", mRootAutomatorObject, READONLY or DONTENUM or PERMANENT)
|
||||
}
|
||||
|
||||
override fun has(name: String?): Boolean {
|
||||
|
||||
@@ -0,0 +1,517 @@
|
||||
package org.autojs.autojs.runtime.api.augment.pinyin
|
||||
|
||||
object Dict {
|
||||
|
||||
/* 带声调字符. */
|
||||
val PHONETIC_SYMBOL = mapOf(
|
||||
"ā" to "a1",
|
||||
"á" to "a2",
|
||||
"ǎ" to "a3",
|
||||
"à" to "a4",
|
||||
"ē" to "e1",
|
||||
"é" to "e2",
|
||||
"ě" to "e3",
|
||||
"è" to "e4",
|
||||
"ō" to "o1",
|
||||
"ó" to "o2",
|
||||
"ǒ" to "o3",
|
||||
"ò" to "o4",
|
||||
"ī" to "i1",
|
||||
"í" to "i2",
|
||||
"ǐ" to "i3",
|
||||
"ì" to "i4",
|
||||
"ū" to "u1",
|
||||
"ú" to "u2",
|
||||
"ǔ" to "u3",
|
||||
"ù" to "u4",
|
||||
"ü" to "v0",
|
||||
"ǘ" to "v2",
|
||||
"ǚ" to "v3",
|
||||
"ǜ" to "v4",
|
||||
"ń" to "n2",
|
||||
"ň" to "n3",
|
||||
"" to "m2",
|
||||
)
|
||||
|
||||
/* 百家姓. */
|
||||
/* https://zh.wikipedia.org/wiki/%E7%99%BE%E5%AE%B6%E5%A7%93 */
|
||||
val SURNAME = mapOf(
|
||||
"赵" to listOf(listOf("zhào")),
|
||||
"钱" to listOf(listOf("qián")),
|
||||
"孙" to listOf(listOf("sūn")),
|
||||
"李" to listOf(listOf("lǐ")),
|
||||
"周" to listOf(listOf("zhōu")),
|
||||
"吴" to listOf(listOf("wú")),
|
||||
"郑" to listOf(listOf("zhèng")),
|
||||
"王" to listOf(listOf("wáng")),
|
||||
"冯" to listOf(listOf("féng")),
|
||||
"陈" to listOf(listOf("chén")),
|
||||
"褚" to listOf(listOf("chǔ")),
|
||||
"卫" to listOf(listOf("wèi")),
|
||||
"蒋" to listOf(listOf("jiǎng")),
|
||||
"沈" to listOf(listOf("shěn")),
|
||||
"韩" to listOf(listOf("hán")),
|
||||
"杨" to listOf(listOf("yáng")),
|
||||
"朱" to listOf(listOf("zhū")),
|
||||
"秦" to listOf(listOf("qín")),
|
||||
"尤" to listOf(listOf("yóu")),
|
||||
"许" to listOf(listOf("xǔ")),
|
||||
"何" to listOf(listOf("hé")),
|
||||
"吕" to listOf(listOf("lǚ")),
|
||||
"施" to listOf(listOf("shī")),
|
||||
"张" to listOf(listOf("zhāng")),
|
||||
"孔" to listOf(listOf("kǒng")),
|
||||
"曹" to listOf(listOf("cáo")),
|
||||
"严" to listOf(listOf("yán")),
|
||||
"华" to listOf(listOf("huà")),
|
||||
"金" to listOf(listOf("jīn")),
|
||||
"魏" to listOf(listOf("wèi")),
|
||||
"陶" to listOf(listOf("táo")),
|
||||
"姜" to listOf(listOf("jiāng")),
|
||||
"戚" to listOf(listOf("qī")),
|
||||
"谢" to listOf(listOf("xiè")),
|
||||
"邹" to listOf(listOf("zōu")),
|
||||
"喻" to listOf(listOf("yù")),
|
||||
"柏" to listOf(listOf("bǎi")),
|
||||
"水" to listOf(listOf("shuǐ")),
|
||||
"窦" to listOf(listOf("dòu")),
|
||||
"章" to listOf(listOf("zhāng")),
|
||||
"云" to listOf(listOf("yún")),
|
||||
"苏" to listOf(listOf("sū")),
|
||||
"潘" to listOf(listOf("pān")),
|
||||
"葛" to listOf(listOf("gě")),
|
||||
"奚" to listOf(listOf("xī")),
|
||||
"范" to listOf(listOf("fàn")),
|
||||
"彭" to listOf(listOf("péng")),
|
||||
"郎" to listOf(listOf("láng")),
|
||||
"鲁" to listOf(listOf("lǔ")),
|
||||
"韦" to listOf(listOf("wéi")),
|
||||
"昌" to listOf(listOf("chāng")),
|
||||
"马" to listOf(listOf("mǎ")),
|
||||
"苗" to listOf(listOf("miáo")),
|
||||
"凤" to listOf(listOf("fèng")),
|
||||
"花" to listOf(listOf("huā")),
|
||||
"方" to listOf(listOf("fāng")),
|
||||
"俞" to listOf(listOf("yú")),
|
||||
"任" to listOf(listOf("rèn")),
|
||||
"袁" to listOf(listOf("yuán")),
|
||||
"柳" to listOf(listOf("liǔ")),
|
||||
"酆" to listOf(listOf("fēng")),
|
||||
"鲍" to listOf(listOf("bào")),
|
||||
"史" to listOf(listOf("shǐ")),
|
||||
"唐" to listOf(listOf("táng")),
|
||||
"费" to listOf(listOf("fèi")),
|
||||
"廉" to listOf(listOf("lián")),
|
||||
"岑" to listOf(listOf("cén")),
|
||||
"薛" to listOf(listOf("xuē")),
|
||||
"雷" to listOf(listOf("léi")),
|
||||
"贺" to listOf(listOf("hè")),
|
||||
"倪" to listOf(listOf("ní")),
|
||||
"汤" to listOf(listOf("tāng")),
|
||||
"滕" to listOf(listOf("téng")),
|
||||
"殷" to listOf(listOf("yīn")),
|
||||
"罗" to listOf(listOf("luó")),
|
||||
"毕" to listOf(listOf("bì")),
|
||||
"郝" to listOf(listOf("hǎo")),
|
||||
"邬" to listOf(listOf("wū")),
|
||||
"安" to listOf(listOf("ān")),
|
||||
"常" to listOf(listOf("cháng")),
|
||||
"乐" to listOf(listOf("yuè")),
|
||||
"于" to listOf(listOf("yú")),
|
||||
"时" to listOf(listOf("shí")),
|
||||
"傅" to listOf(listOf("fù")),
|
||||
"皮" to listOf(listOf("pí")),
|
||||
"卞" to listOf(listOf("biàn")),
|
||||
"齐" to listOf(listOf("qí")),
|
||||
"康" to listOf(listOf("kāng")),
|
||||
"伍" to listOf(listOf("wǔ")),
|
||||
"余" to listOf(listOf("yú")),
|
||||
"元" to listOf(listOf("yuán")),
|
||||
"卜" to listOf(listOf("bǔ")),
|
||||
"顾" to listOf(listOf("gù")),
|
||||
"孟" to listOf(listOf("mèng")),
|
||||
"平" to listOf(listOf("píng")),
|
||||
"黄" to listOf(listOf("huáng")),
|
||||
"和" to listOf(listOf("hé")),
|
||||
"穆" to listOf(listOf("mù")),
|
||||
"萧" to listOf(listOf("xiāo")),
|
||||
"尹" to listOf(listOf("yǐn")),
|
||||
"姚" to listOf(listOf("yáo")),
|
||||
"邵" to listOf(listOf("shào")),
|
||||
"湛" to listOf(listOf("zhàn")),
|
||||
"汪" to listOf(listOf("wāng")),
|
||||
"祁" to listOf(listOf("qí")),
|
||||
"毛" to listOf(listOf("máo")),
|
||||
"禹" to listOf(listOf("yǔ")),
|
||||
"狄" to listOf(listOf("dí")),
|
||||
"米" to listOf(listOf("mǐ")),
|
||||
"贝" to listOf(listOf("bèi")),
|
||||
"明" to listOf(listOf("míng")),
|
||||
"臧" to listOf(listOf("zāng")),
|
||||
"计" to listOf(listOf("jì")),
|
||||
"伏" to listOf(listOf("fú")),
|
||||
"成" to listOf(listOf("chéng")),
|
||||
"戴" to listOf(listOf("dài")),
|
||||
"谈" to listOf(listOf("tán")),
|
||||
"宋" to listOf(listOf("sòng")),
|
||||
"茅" to listOf(listOf("máo")),
|
||||
"庞" to listOf(listOf("páng")),
|
||||
"熊" to listOf(listOf("xióng")),
|
||||
"纪" to listOf(listOf("jì")),
|
||||
"舒" to listOf(listOf("shū")),
|
||||
"屈" to listOf(listOf("qū")),
|
||||
"项" to listOf(listOf("xiàng")),
|
||||
"祝" to listOf(listOf("zhù")),
|
||||
"董" to listOf(listOf("dǒng")),
|
||||
"梁" to listOf(listOf("liáng")),
|
||||
"杜" to listOf(listOf("dù")),
|
||||
"阮" to listOf(listOf("ruǎn")),
|
||||
"蓝" to listOf(listOf("lán")),
|
||||
"闵" to listOf(listOf("mǐn")),
|
||||
"席" to listOf(listOf("xí")),
|
||||
"季" to listOf(listOf("jì")),
|
||||
"麻" to listOf(listOf("má")),
|
||||
"强" to listOf(listOf("qiáng")),
|
||||
"贾" to listOf(listOf("jiǎ")),
|
||||
"路" to listOf(listOf("lù")),
|
||||
"娄" to listOf(listOf("lóu")),
|
||||
"危" to listOf(listOf("wēi")),
|
||||
"江" to listOf(listOf("jiāng")),
|
||||
"童" to listOf(listOf("tóng")),
|
||||
"颜" to listOf(listOf("yán")),
|
||||
"郭" to listOf(listOf("guō")),
|
||||
"梅" to listOf(listOf("méi")),
|
||||
"盛" to listOf(listOf("shèng")),
|
||||
"林" to listOf(listOf("lín")),
|
||||
"刁" to listOf(listOf("diāo")),
|
||||
"钟" to listOf(listOf("zhōng")),
|
||||
"徐" to listOf(listOf("xú")),
|
||||
"邱" to listOf(listOf("qiū")),
|
||||
"骆" to listOf(listOf("luò")),
|
||||
"高" to listOf(listOf("gāo")),
|
||||
"夏" to listOf(listOf("xià")),
|
||||
"蔡" to listOf(listOf("cài")),
|
||||
"田" to listOf(listOf("tián")),
|
||||
"樊" to listOf(listOf("fán")),
|
||||
"胡" to listOf(listOf("hú")),
|
||||
"凌" to listOf(listOf("líng")),
|
||||
"霍" to listOf(listOf("huò")),
|
||||
"虞" to listOf(listOf("yú")),
|
||||
"万" to listOf(listOf("wàn")),
|
||||
"支" to listOf(listOf("zhī")),
|
||||
"柯" to listOf(listOf("kē")),
|
||||
"昝" to listOf(listOf("zǎn")),
|
||||
"管" to listOf(listOf("guǎn")),
|
||||
"卢" to listOf(listOf("lú")),
|
||||
"莫" to listOf(listOf("mò")),
|
||||
"经" to listOf(listOf("jīng")),
|
||||
"房" to listOf(listOf("fáng")),
|
||||
"裘" to listOf(listOf("qiú")),
|
||||
"缪" to listOf(listOf("miào")),
|
||||
"干" to listOf(listOf("gān")),
|
||||
"解" to listOf(listOf("xiè")),
|
||||
"应" to listOf(listOf("yīng")),
|
||||
"宗" to listOf(listOf("zōng")),
|
||||
"丁" to listOf(listOf("dīng")),
|
||||
"宣" to listOf(listOf("xuān")),
|
||||
"贲" to listOf(listOf("bēn")),
|
||||
"邓" to listOf(listOf("dèng")),
|
||||
"郁" to listOf(listOf("yù")),
|
||||
"单" to listOf(listOf("shàn")),
|
||||
"杭" to listOf(listOf("háng")),
|
||||
"洪" to listOf(listOf("hóng")),
|
||||
"包" to listOf(listOf("bāo")),
|
||||
"诸" to listOf(listOf("zhū")),
|
||||
"左" to listOf(listOf("zuǒ")),
|
||||
"石" to listOf(listOf("shí")),
|
||||
"崔" to listOf(listOf("cuī")),
|
||||
"吉" to listOf(listOf("jí")),
|
||||
"钮" to listOf(listOf("niǔ")),
|
||||
"龚" to listOf(listOf("gōng")),
|
||||
"程" to listOf(listOf("chéng")),
|
||||
"嵇" to listOf(listOf("jī")),
|
||||
"邢" to listOf(listOf("xíng")),
|
||||
"滑" to listOf(listOf("huá")),
|
||||
"裴" to listOf(listOf("péi")),
|
||||
"陆" to listOf(listOf("lù")),
|
||||
"荣" to listOf(listOf("róng")),
|
||||
"翁" to listOf(listOf("wēng")),
|
||||
"荀" to listOf(listOf("xún")),
|
||||
"羊" to listOf(listOf("yáng")),
|
||||
"於" to listOf(listOf("yū")),
|
||||
"惠" to listOf(listOf("huì")),
|
||||
"甄" to listOf(listOf("zhēn")),
|
||||
"曲" to listOf(listOf("qū")),
|
||||
"家" to listOf(listOf("jiā")),
|
||||
"封" to listOf(listOf("fēng")),
|
||||
"芮" to listOf(listOf("ruì")),
|
||||
"羿" to listOf(listOf("yì")),
|
||||
"储" to listOf(listOf("chǔ")),
|
||||
"靳" to listOf(listOf("jìn")),
|
||||
"汲" to listOf(listOf("jí")),
|
||||
"邴" to listOf(listOf("bǐng")),
|
||||
"糜" to listOf(listOf("mí")),
|
||||
"松" to listOf(listOf("sōng")),
|
||||
"井" to listOf(listOf("jǐng")),
|
||||
"段" to listOf(listOf("duàn")),
|
||||
"富" to listOf(listOf("fù")),
|
||||
"巫" to listOf(listOf("wū")),
|
||||
"乌" to listOf(listOf("wū")),
|
||||
"焦" to listOf(listOf("jiāo")),
|
||||
"巴" to listOf(listOf("bā")),
|
||||
"弓" to listOf(listOf("gōng")),
|
||||
"牧" to listOf(listOf("mù")),
|
||||
"隗" to listOf(listOf("kuí")),
|
||||
"山" to listOf(listOf("shān")),
|
||||
"谷" to listOf(listOf("gǔ")),
|
||||
"车" to listOf(listOf("chē")),
|
||||
"侯" to listOf(listOf("hóu")),
|
||||
"宓" to listOf(listOf("mì")),
|
||||
"蓬" to listOf(listOf("péng")),
|
||||
"全" to listOf(listOf("quán")),
|
||||
"郗" to listOf(listOf("xī")),
|
||||
"班" to listOf(listOf("bān")),
|
||||
"仰" to listOf(listOf("yǎng")),
|
||||
"秋" to listOf(listOf("qiū")),
|
||||
"仲" to listOf(listOf("zhòng")),
|
||||
"伊" to listOf(listOf("yī")),
|
||||
"宫" to listOf(listOf("gōng")),
|
||||
"宁" to listOf(listOf("nìng")),
|
||||
"仇" to listOf(listOf("qiú")),
|
||||
"栾" to listOf(listOf("luán")),
|
||||
"暴" to listOf(listOf("bào")),
|
||||
"甘" to listOf(listOf("gān")),
|
||||
"钭" to listOf(listOf("tǒu")),
|
||||
"厉" to listOf(listOf("lì")),
|
||||
"戎" to listOf(listOf("róng")),
|
||||
"祖" to listOf(listOf("zǔ")),
|
||||
"武" to listOf(listOf("wǔ")),
|
||||
"符" to listOf(listOf("fú")),
|
||||
"刘" to listOf(listOf("liú")),
|
||||
"景" to listOf(listOf("jǐng")),
|
||||
"詹" to listOf(listOf("zhān")),
|
||||
"束" to listOf(listOf("shù")),
|
||||
"龙" to listOf(listOf("lóng")),
|
||||
"叶" to listOf(listOf("yè")),
|
||||
"幸" to listOf(listOf("xìng")),
|
||||
"司" to listOf(listOf("sī")),
|
||||
"韶" to listOf(listOf("sháo")),
|
||||
"郜" to listOf(listOf("gào")),
|
||||
"黎" to listOf(listOf("lí")),
|
||||
"蓟" to listOf(listOf("jì")),
|
||||
"薄" to listOf(listOf("bó")),
|
||||
"印" to listOf(listOf("yìn")),
|
||||
"宿" to listOf(listOf("sù")),
|
||||
"白" to listOf(listOf("bái")),
|
||||
"怀" to listOf(listOf("huái")),
|
||||
"蒲" to listOf(listOf("pú")),
|
||||
"邰" to listOf(listOf("tái")),
|
||||
"从" to listOf(listOf("cóng")),
|
||||
"鄂" to listOf(listOf("è")),
|
||||
"索" to listOf(listOf("suǒ")),
|
||||
"咸" to listOf(listOf("xián")),
|
||||
"籍" to listOf(listOf("jí")),
|
||||
"赖" to listOf(listOf("lài")),
|
||||
"卓" to listOf(listOf("zhuó")),
|
||||
"蔺" to listOf(listOf("lìn")),
|
||||
"屠" to listOf(listOf("tú")),
|
||||
"蒙" to listOf(listOf("méng")),
|
||||
"池" to listOf(listOf("chí")),
|
||||
"乔" to listOf(listOf("qiáo")),
|
||||
"阴" to listOf(listOf("yīn")),
|
||||
"鬱" to listOf(listOf("yù")),
|
||||
"胥" to listOf(listOf("xū")),
|
||||
"能" to listOf(listOf("nài")),
|
||||
"苍" to listOf(listOf("cāng")),
|
||||
"双" to listOf(listOf("shuāng")),
|
||||
"闻" to listOf(listOf("wén")),
|
||||
"莘" to listOf(listOf("shēn")),
|
||||
"党" to listOf(listOf("dǎng")),
|
||||
"翟" to listOf(listOf("zhái")),
|
||||
"谭" to listOf(listOf("tán")),
|
||||
"贡" to listOf(listOf("gòng")),
|
||||
"劳" to listOf(listOf("láo")),
|
||||
"逄" to listOf(listOf("páng")),
|
||||
"姬" to listOf(listOf("jī")),
|
||||
"申" to listOf(listOf("shēn")),
|
||||
"扶" to listOf(listOf("fú")),
|
||||
"堵" to listOf(listOf("dǔ")),
|
||||
"冉" to listOf(listOf("rǎn")),
|
||||
"宰" to listOf(listOf("zǎi")),
|
||||
"郦" to listOf(listOf("lì")),
|
||||
"雍" to listOf(listOf("yōng")),
|
||||
"郤" to listOf(listOf("xì")),
|
||||
"璩" to listOf(listOf("qú")),
|
||||
"桑" to listOf(listOf("sāng")),
|
||||
"桂" to listOf(listOf("guì")),
|
||||
"濮" to listOf(listOf("pú")),
|
||||
"牛" to listOf(listOf("niú")),
|
||||
"寿" to listOf(listOf("shòu")),
|
||||
"通" to listOf(listOf("tōng")),
|
||||
"边" to listOf(listOf("biān")),
|
||||
"扈" to listOf(listOf("hù")),
|
||||
"燕" to listOf(listOf("yān")),
|
||||
"冀" to listOf(listOf("jì")),
|
||||
"郏" to listOf(listOf("jiá")),
|
||||
"浦" to listOf(listOf("pǔ")),
|
||||
"尚" to listOf(listOf("shàng")),
|
||||
"农" to listOf(listOf("nóng")),
|
||||
"温" to listOf(listOf("wēn")),
|
||||
"别" to listOf(listOf("bié")),
|
||||
"庄" to listOf(listOf("zhuāng")),
|
||||
"晏" to listOf(listOf("yàn")),
|
||||
"柴" to listOf(listOf("chái")),
|
||||
"瞿" to listOf(listOf("qú")),
|
||||
"阎" to listOf(listOf("yán")),
|
||||
"充" to listOf(listOf("chōng")),
|
||||
"慕" to listOf(listOf("mù")),
|
||||
"连" to listOf(listOf("lián")),
|
||||
"茹" to listOf(listOf("rú")),
|
||||
"习" to listOf(listOf("xí")),
|
||||
"宦" to listOf(listOf("huàn")),
|
||||
"艾" to listOf(listOf("ài")),
|
||||
"鱼" to listOf(listOf("yú")),
|
||||
"容" to listOf(listOf("róng")),
|
||||
"向" to listOf(listOf("xiàng")),
|
||||
"古" to listOf(listOf("gǔ")),
|
||||
"易" to listOf(listOf("yì")),
|
||||
"慎" to listOf(listOf("shèn")),
|
||||
"戈" to listOf(listOf("gē")),
|
||||
"廖" to listOf(listOf("liào")),
|
||||
"庾" to listOf(listOf("yǔ")),
|
||||
"终" to listOf(listOf("zhōng")),
|
||||
"暨" to listOf(listOf("jì")),
|
||||
"居" to listOf(listOf("jū")),
|
||||
"衡" to listOf(listOf("héng")),
|
||||
"步" to listOf(listOf("bù")),
|
||||
"都" to listOf(listOf("dū")),
|
||||
"耿" to listOf(listOf("gěng")),
|
||||
"满" to listOf(listOf("mǎn")),
|
||||
"弘" to listOf(listOf("hóng")),
|
||||
"匡" to listOf(listOf("kuāng")),
|
||||
"国" to listOf(listOf("guó")),
|
||||
"文" to listOf(listOf("wén")),
|
||||
"寇" to listOf(listOf("kòu")),
|
||||
"广" to listOf(listOf("guǎng")),
|
||||
"禄" to listOf(listOf("lù")),
|
||||
"阙" to listOf(listOf("quē")),
|
||||
"东" to listOf(listOf("dōng")),
|
||||
"欧" to listOf(listOf("ōu")),
|
||||
"殳" to listOf(listOf("shū")),
|
||||
"沃" to listOf(listOf("wò")),
|
||||
"利" to listOf(listOf("lì")),
|
||||
"蔚" to listOf(listOf("wèi")),
|
||||
"越" to listOf(listOf("yuè")),
|
||||
"夔" to listOf(listOf("kuí")),
|
||||
"隆" to listOf(listOf("lóng")),
|
||||
"师" to listOf(listOf("shī")),
|
||||
"巩" to listOf(listOf("gǒng")),
|
||||
"厍" to listOf(listOf("shè")),
|
||||
"聂" to listOf(listOf("niè")),
|
||||
"晁" to listOf(listOf("cháo")),
|
||||
"勾" to listOf(listOf("gōu")),
|
||||
"敖" to listOf(listOf("áo")),
|
||||
"融" to listOf(listOf("róng")),
|
||||
"冷" to listOf(listOf("lěng")),
|
||||
"訾" to listOf(listOf("zǐ")),
|
||||
"辛" to listOf(listOf("xīn")),
|
||||
"阚" to listOf(listOf("kàn")),
|
||||
"那" to listOf(listOf("nā")),
|
||||
"简" to listOf(listOf("jiǎn")),
|
||||
"饶" to listOf(listOf("ráo")),
|
||||
"空" to listOf(listOf("kōng")),
|
||||
"曾" to listOf(listOf("zēng")),
|
||||
"母" to listOf(listOf("mǔ")),
|
||||
"沙" to listOf(listOf("shā")),
|
||||
"乜" to listOf(listOf("niè")),
|
||||
"养" to listOf(listOf("yǎng")),
|
||||
"鞠" to listOf(listOf("jū")),
|
||||
"须" to listOf(listOf("xū")),
|
||||
"丰" to listOf(listOf("fēng")),
|
||||
"巢" to listOf(listOf("cháo")),
|
||||
"关" to listOf(listOf("guān")),
|
||||
"蒯" to listOf(listOf("kuǎi")),
|
||||
"相" to listOf(listOf("xiàng")),
|
||||
"查" to listOf(listOf("zhā")),
|
||||
"后" to listOf(listOf("hòu")),
|
||||
"荆" to listOf(listOf("jīng")),
|
||||
"红" to listOf(listOf("hóng")),
|
||||
"游" to listOf(listOf("yóu")),
|
||||
"竺" to listOf(listOf("zhú")),
|
||||
"权" to listOf(listOf("quán")),
|
||||
"逯" to listOf(listOf("lù")),
|
||||
"盖" to listOf(listOf("gài")),
|
||||
"益" to listOf(listOf("yì")),
|
||||
"桓" to listOf(listOf("huán")),
|
||||
"公" to listOf(listOf("gōng")),
|
||||
"牟" to listOf(listOf("móu")),
|
||||
"哈" to listOf(listOf("hǎ")),
|
||||
"言" to listOf(listOf("yán")),
|
||||
"福" to listOf(listOf("fú")),
|
||||
)
|
||||
|
||||
/* 复姓. */
|
||||
val COMPOUND_SURNAME = mapOf(
|
||||
"万俟" to listOf(listOf("mò"), listOf("qí")),
|
||||
"上官" to listOf(listOf("shàng"), listOf("guān")),
|
||||
"东方" to listOf(listOf("dōng"), listOf("fāng")),
|
||||
"东郭" to listOf(listOf("dōng"), listOf("guō")),
|
||||
"东门" to listOf(listOf("dōng"), listOf("mén")),
|
||||
"乐正" to listOf(listOf("yuè"), listOf("zhèng")),
|
||||
"亓官" to listOf(listOf("qí"), listOf("guān")),
|
||||
"仉督" to listOf(listOf("zhǎng"), listOf("dū")),
|
||||
"令狐" to listOf(listOf("líng"), listOf("hú")),
|
||||
"仲孙" to listOf(listOf("zhòng"), listOf("sūn")),
|
||||
"公冶" to listOf(listOf("gōng"), listOf("yě")),
|
||||
"公孙" to listOf(listOf("gōng"), listOf("sūn")),
|
||||
"公羊" to listOf(listOf("gōng"), listOf("yáng")),
|
||||
"公良" to listOf(listOf("gōng"), listOf("liáng")),
|
||||
"公西" to listOf(listOf("gōng"), listOf("xī")),
|
||||
"单于" to listOf(listOf("chán"), listOf("yú")),
|
||||
"南宫" to listOf(listOf("nán"), listOf("gōng")),
|
||||
"南门" to listOf(listOf("nán"), listOf("mén")),
|
||||
"司寇" to listOf(listOf("sī"), listOf("kòu")),
|
||||
"司徒" to listOf(listOf("sī"), listOf("tú")),
|
||||
"司空" to listOf(listOf("sī"), listOf("kōng")),
|
||||
"司马" to listOf(listOf("sī"), listOf("mǎ")),
|
||||
"呼延" to listOf(listOf("hū"), listOf("yán")),
|
||||
"壤驷" to listOf(listOf("rǎng"), listOf("sì")),
|
||||
"夏侯" to listOf(listOf("xià"), listOf("hóu")),
|
||||
"太叔" to listOf(listOf("tài"), listOf("shū")),
|
||||
"夹谷" to listOf(listOf("jiá"), listOf("gǔ")),
|
||||
"子车" to listOf(listOf("zǐ"), listOf("jū")),
|
||||
"宇文" to listOf(listOf("yǔ"), listOf("wén")),
|
||||
"宗政" to listOf(listOf("zōng"), listOf("zhèng")),
|
||||
"宰父" to listOf(listOf("zǎi"), listOf("fǔ")),
|
||||
"尉迟" to listOf(listOf("yù"), listOf("chí")),
|
||||
"左丘" to listOf(listOf("zuǒ"), listOf("qiū")),
|
||||
"巫马" to listOf(listOf("wū"), listOf("mǎ")),
|
||||
"慕容" to listOf(listOf("mù"), listOf("róng")),
|
||||
"拓跋" to listOf(listOf("tuò"), listOf("bá")),
|
||||
"梁丘" to listOf(listOf("liáng"), listOf("qiū")),
|
||||
"榖梁" to listOf(listOf("gǔ"), listOf("liáng")),
|
||||
"欧阳" to listOf(listOf("ōu"), listOf("yáng")),
|
||||
"段干" to listOf(listOf("duàn"), listOf("gān")),
|
||||
"淳于" to listOf(listOf("chún"), listOf("yú")),
|
||||
"漆雕" to listOf(listOf("qī"), listOf("diāo")),
|
||||
"澹台" to listOf(listOf("tán"), listOf("tái")),
|
||||
"濮阳" to listOf(listOf("pú"), listOf("yáng")),
|
||||
"申屠" to listOf(listOf("shēn"), listOf("tú")),
|
||||
"百里" to listOf(listOf("bǎi"), listOf("lǐ")),
|
||||
"皇甫" to listOf(listOf("huáng"), listOf("pǔ")),
|
||||
"端木" to listOf(listOf("duān"), listOf("mù")),
|
||||
"第五" to listOf(listOf("dì"), listOf("wǔ")),
|
||||
"羊舌" to listOf(listOf("yáng"), listOf("shé")),
|
||||
"西门" to listOf(listOf("xī"), listOf("mén")),
|
||||
"诸葛" to listOf(listOf("zhū"), listOf("gě")),
|
||||
"赫连" to listOf(listOf("hè"), listOf("lián")),
|
||||
"轩辕" to listOf(listOf("xuān"), listOf("yuán")),
|
||||
"钟离" to listOf(listOf("zhōng"), listOf("lí")),
|
||||
"长孙" to listOf(listOf("zhǎng"), listOf("sūn")),
|
||||
"闻人" to listOf(listOf("wén"), listOf("rén")),
|
||||
"闾丘" to listOf(listOf("lǘ"), listOf("qiū")),
|
||||
"颛孙" to listOf(listOf("zhuān"), listOf("sūn")),
|
||||
"鲜于" to listOf(listOf("xiān"), listOf("yú")),
|
||||
)
|
||||
|
||||
}
|
||||
@@ -1,178 +1,263 @@
|
||||
package org.autojs.autojs.runtime.api.augment.pinyin
|
||||
|
||||
import net.sourceforge.pinyin4j.PinyinHelper
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType.LOWERCASE
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType.UPPERCASE
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType.WITHOUT_TONE
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType.WITH_TONE_MARK
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType.WITH_TONE_NUMBER
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType.WITH_U_AND_COLON
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType.WITH_U_UNICODE
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType.WITH_V
|
||||
import com.huaban.analysis.jieba.CharsDictionaryDatabase
|
||||
import com.huaban.analysis.jieba.JiebaSegmenter
|
||||
import com.huaban.analysis.jieba.PhrasesDictionaryDatabase
|
||||
import org.autojs.autojs.annotation.RhinoSingletonFunctionInterface
|
||||
import org.autojs.autojs.extension.ArrayExtensions.toNativeArray
|
||||
import org.autojs.autojs.extension.ScriptableExtensions.defineProp
|
||||
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
|
||||
import org.autojs.autojs.runtime.api.augment.Augmentable
|
||||
import org.autojs.autojs.runtime.api.augment.Invokable
|
||||
import org.autojs.autojs.runtime.api.augment.pinyin.PinyinCore.DefaultOptions
|
||||
import org.autojs.autojs.runtime.api.augment.pinyin.PinyinCore.PinyinMode
|
||||
import org.autojs.autojs.runtime.api.augment.pinyin.PinyinCore.PinyinStyle
|
||||
import org.autojs.autojs.runtime.api.augment.pinyin.PinyinCore.parseStyle
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceBoolean
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceIntNumber
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceString
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceStringUppercase
|
||||
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||
import org.autojs.autojs.util.RhinoUtils.withRhinoContext
|
||||
import org.mozilla.javascript.BoundFunction
|
||||
import org.mozilla.javascript.Context
|
||||
import org.mozilla.javascript.NativeArray
|
||||
import org.mozilla.javascript.NativeJavaMethod
|
||||
import org.mozilla.javascript.NativeObject
|
||||
import org.mozilla.javascript.Scriptable
|
||||
import org.mozilla.javascript.ScriptableObject.DONTENUM
|
||||
import org.mozilla.javascript.ScriptableObject.PERMANENT
|
||||
import org.mozilla.javascript.ScriptableObject.READONLY
|
||||
|
||||
object Pinyin : Augmentable(), Invokable {
|
||||
|
||||
private const val DEFAULT_SEPARATOR = ""
|
||||
private val charsDictDatabase by lazy { CharsDictionaryDatabase.getInstance(globalContext).database }
|
||||
private val phrasesDictDatabase by lazy { PhrasesDictionaryDatabase.getInstance(globalContext).database }
|
||||
|
||||
private const val DEFAULT_CASE_TYPE_STRING = "LOWERCASE"
|
||||
private val DEFAULT_CASE_TYPE = LOWERCASE
|
||||
|
||||
private const val DEFAULT_TONE_TYPE_STRING = "WITHOUT_TONE"
|
||||
private val DEFAULT_TONE_TYPE = WITHOUT_TONE
|
||||
|
||||
private const val DEFAULT_V_CHAR_TYPE_STRING = "WITH_V"
|
||||
private val DEFAULT_V_CHAR_TYPE = WITH_V
|
||||
|
||||
private val pinyinToneMap = mapOf(
|
||||
// 单韵母
|
||||
"a1" to "ā", "a2" to "á", "a3" to "ǎ", "a4" to "à", "a0" to "a",
|
||||
"o1" to "ō", "o2" to "ó", "o3" to "ǒ", "o4" to "ò", "o0" to "o",
|
||||
"e1" to "ē", "e2" to "é", "e3" to "ě", "e4" to "è", "e0" to "e",
|
||||
"i1" to "ī", "i2" to "í", "i3" to "ǐ", "i4" to "ì", "i0" to "i",
|
||||
"u1" to "ū", "u2" to "ú", "u3" to "ǔ", "u4" to "ù", "u0" to "u",
|
||||
"ü1" to "ǖ", "ü2" to "ǘ", "ü3" to "ǚ", "ü4" to "ǜ", "ü0" to "ü",
|
||||
"v1" to "ǖ", "v2" to "ǘ", "v3" to "ǚ", "v4" to "ǜ", "v0" to "ü",
|
||||
"u:1" to "ǖ", "u:2" to "ǘ", "u:3" to "ǚ", "u:4" to "ǜ", "u:0" to "ü",
|
||||
|
||||
// 复韵母 - 普通
|
||||
"ai1" to "āi", "ai2" to "ái", "ai3" to "ǎi", "ai4" to "ài", "ai0" to "ai",
|
||||
"ei1" to "ēi", "ei2" to "éi", "ei3" to "ěi", "ei4" to "èi", "ei0" to "ei",
|
||||
"ui1" to "uī", "ui2" to "uí", "ui3" to "uǐ", "ui4" to "uì", "ui0" to "ui",
|
||||
"ao1" to "āo", "ao2" to "áo", "ao3" to "ǎo", "ao4" to "ào", "ao0" to "ao",
|
||||
"ou1" to "ōu", "ou2" to "óu", "ou3" to "ǒu", "ou4" to "òu", "ou0" to "ou",
|
||||
"iu1" to "iū", "iu2" to "iú", "iu3" to "iǔ", "iu4" to "iù", "iu0" to "iu",
|
||||
"ie1" to "iē", "ie2" to "ié", "ie3" to "iě", "ie4" to "iè", "ie0" to "ie",
|
||||
"üe1" to "üē", "üe2" to "üé", "üe3" to "üě", "üe4" to "üè", "üe0" to "üe",
|
||||
"u:e1" to "üē", "u:e2" to "üé", "u:e3" to "üě", "u:e4" to "üè", "u:e0" to "üe",
|
||||
"ve1" to "üē", "ve2" to "üé", "ve3" to "üě", "ve4" to "üè", "ve0" to "üe",
|
||||
|
||||
// 复韵母 - 特殊
|
||||
"er1" to "ēr", "er2" to "ér", "er3" to "ěr", "er4" to "èr", "er0" to "er",
|
||||
|
||||
// 复韵母 - 前鼻韵母
|
||||
"an1" to "ān", "an2" to "án", "an3" to "ǎn", "an4" to "àn", "an0" to "an",
|
||||
"en1" to "ēn", "en2" to "én", "en3" to "ěn", "en4" to "èn", "en0" to "en",
|
||||
"in1" to "īn", "in2" to "ín", "in3" to "ǐn", "in4" to "ìn", "in0" to "in",
|
||||
"un1" to "ūn", "un2" to "ún", "un3" to "ǔn", "un4" to "ùn", "un0" to "un",
|
||||
"ün1" to "ǖn", "ün2" to "ǘn", "ün3" to "ǚn", "ün4" to "ǜn", "ün0" to "ün",
|
||||
"u:n1" to "ǖn", "u:n2" to "ǘn", "u:n3" to "ǚn", "u:n4" to "ǜn", "u:n0" to "ün",
|
||||
"vn1" to "ǖn", "vn2" to "ǘn", "vn3" to "ǚn", "vn4" to "ǜn", "vn0" to "ün",
|
||||
|
||||
// 复韵母 - 后鼻韵母
|
||||
"ang1" to "āng", "ang2" to "áng", "ang3" to "ǎng", "ang4" to "àng", "ang0" to "ang",
|
||||
"eng1" to "ēng", "eng2" to "éng", "eng3" to "ěng", "eng4" to "èng", "eng0" to "eng",
|
||||
"ing1" to "īng", "ing2" to "íng", "ing3" to "ǐng", "ing4" to "ìng", "ing0" to "ing",
|
||||
"ong1" to "ōng", "ong2" to "óng", "ong3" to "ǒng", "ong4" to "òng", "ong0" to "ong"
|
||||
@Suppress("SpellCheckingInspection")
|
||||
override val selfAssignmentProperties = listOf(
|
||||
"STYLE_NORMAL" to PinyinStyle.NORMAL,
|
||||
"STYLE_TONE" to PinyinStyle.TONE,
|
||||
"STYLE_TONE2" to PinyinStyle.TONE2,
|
||||
"STYLE_TO3NE" to PinyinStyle.TO3NE,
|
||||
"STYLE_INITIALS" to PinyinStyle.INITIALS,
|
||||
"STYLE_FIRST_LETTER" to PinyinStyle.FIRST_LETTER,
|
||||
"MODE_NORMAL" to PinyinMode.NORMAL,
|
||||
"MODE_SURNAME" to PinyinMode.SURNAME,
|
||||
"MODE_PLACENAME" to PinyinMode.PLACE_NAME,
|
||||
"MODE_PLACE_NAME" to PinyinMode.PLACE_NAME,
|
||||
)
|
||||
|
||||
override val selfAssignmentFunctions = listOf(
|
||||
::`as`.name,
|
||||
::of.name,
|
||||
::convert.name,
|
||||
::simple.name,
|
||||
::compare.name,
|
||||
::compact.name,
|
||||
::fromCodePoint.name,
|
||||
::fromPhrase.name,
|
||||
)
|
||||
|
||||
@RhinoSingletonFunctionInterface
|
||||
override fun invoke(args: Array<out Any?>): String = ensureArgumentsLengthInRange(args, 1..2) { argList ->
|
||||
of(argList)
|
||||
override fun invoke(args: Array<out Any?>): NativeArray = ensureArgumentsLengthInRange(args, 1..2) { argList ->
|
||||
convert(argList)
|
||||
}
|
||||
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun of(args: Array<out Any?>): String = ensureArgumentsLengthInRange(args, 1..2) { argList ->
|
||||
val (string, options) = argList
|
||||
|
||||
val str = coerceString(string, "").takeIf { it.isNotEmpty() } ?: return@ensureArgumentsLengthInRange ""
|
||||
var separator = DEFAULT_SEPARATOR
|
||||
val opt = when (options) {
|
||||
is String -> newNativeObject().also { separator = options }
|
||||
is NativeObject -> options
|
||||
else -> newNativeObject()
|
||||
}
|
||||
|
||||
separator = opt.inquire(listOf("separator", "sep"), ::coerceString, separator)
|
||||
|
||||
val caseType = when (val case = opt.inquire(listOf("case", "caseType"))) {
|
||||
is HanyuPinyinCaseType -> case
|
||||
else -> when (coerceStringUppercase(case, DEFAULT_CASE_TYPE_STRING)) {
|
||||
"LOWERCASE", "LOW", "L", "0" -> LOWERCASE
|
||||
"UPPERCASE", "UP", "U", "1" -> UPPERCASE
|
||||
else -> throw IllegalArgumentException("Invalid case type: ${Context.toString(case)}")
|
||||
fun convert(args: Array<out Any?>): NativeArray = ensureArgumentsLengthInRange(args, 1..2) { argList ->
|
||||
val (hansArg, options) = argList
|
||||
val hans = coerceString(hansArg, "")
|
||||
val opt = options as? NativeObject ?: newNativeObject()
|
||||
convertRhino(hans, opt).map { it.toNativeArray() }.toNativeArray().also { result ->
|
||||
val funcName = "compact"
|
||||
withRhinoContext { cx ->
|
||||
val thisObj = Context.javaToJS(Util, result) as Scriptable
|
||||
val boundFunction = BoundFunction(
|
||||
/* cx = */ cx,
|
||||
/* scope = */ result,
|
||||
/* targetFunction = */ NativeJavaMethod(Util::class.java.methods.find { it.name == funcName }, funcName),
|
||||
/* boundThis = */ thisObj,
|
||||
/* boundArgs = */ arrayOf(result),
|
||||
)
|
||||
result.defineProp(funcName, boundFunction, READONLY or DONTENUM or PERMANENT)
|
||||
}
|
||||
}
|
||||
val toneType = when (val tone = opt.inquire(listOf("tone", "toneType"))) {
|
||||
is HanyuPinyinToneType -> tone
|
||||
else -> when (coerceStringUppercase(tone, DEFAULT_TONE_TYPE_STRING)) {
|
||||
"WITH_TONE_NUMBER", "WITH_NUMBER", "NUMBER", "NUM" -> WITH_TONE_NUMBER
|
||||
"WITHOUT_TONE", "NO_TONE", "NO", "FALSE", "0" -> WITHOUT_TONE
|
||||
"WITH_TONE_MARK", "WITH_MARK", "MARK", "TRUE", "1" -> WITH_TONE_MARK
|
||||
else -> throw IllegalArgumentException("Invalid tone type: ${Context.toString(tone)}")
|
||||
}
|
||||
}
|
||||
val vCharType = when (val vChar = opt.inquire(listOf("v", "vChar", "vCharType"))) {
|
||||
is HanyuPinyinVCharType -> vChar
|
||||
else -> when (coerceStringUppercase(vChar, if (toneType == WITH_TONE_MARK) "WITH_U_UNICODE" else DEFAULT_V_CHAR_TYPE_STRING)) {
|
||||
"WITH_U_AND_COLON", "U_AND_COLON", "U_COLON", "U:" -> WITH_U_AND_COLON
|
||||
"WITH_V", "V" -> WITH_V
|
||||
"WITH_U_UNICODE", "U_UNICODE", "UNICODE", "Ü" -> WITH_U_UNICODE
|
||||
else -> throw IllegalArgumentException("Invalid v char type: ${Context.toString(vChar)}")
|
||||
}
|
||||
}
|
||||
ofRhino(str, separator, caseType, toneType, vCharType)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun ofRhino(
|
||||
str: String,
|
||||
separator: String = DEFAULT_SEPARATOR,
|
||||
caseType: HanyuPinyinCaseType = DEFAULT_CASE_TYPE,
|
||||
toneType: HanyuPinyinToneType = DEFAULT_TONE_TYPE,
|
||||
vCharType: HanyuPinyinVCharType = DEFAULT_V_CHAR_TYPE,
|
||||
): String {
|
||||
val format = HanyuPinyinOutputFormat().also {
|
||||
it.caseType = caseType
|
||||
it.toneType = toneType
|
||||
it.vCharType = vCharType
|
||||
}
|
||||
|
||||
val pinyinResult = StringBuilder()
|
||||
|
||||
str.forEach { ch ->
|
||||
val pinyin = when (ch) {
|
||||
in '\u4E00'..'\u9FA5' -> {
|
||||
PinyinHelper.toHanyuPinyinStringArray(ch, format)?.firstOrNull() ?: ""
|
||||
fun convertRhino(hans: String, opt: NativeObject): List<List<String>> = when {
|
||||
hans.isEmpty() -> listOf()
|
||||
else -> {
|
||||
val phrases: List<String> = when {
|
||||
opt.inquire("segment", ::coerceBoolean, DefaultOptions.SEGMENT) -> {
|
||||
segment(hans)
|
||||
}
|
||||
else -> ch.toString()
|
||||
else -> groupChineseAndNonChinese(hans)
|
||||
}
|
||||
pinyinResult.append(pinyin).append(separator)
|
||||
}
|
||||
var nonHans = ""
|
||||
|
||||
return pinyinResult.toString().trim()
|
||||
when (PinyinMode.SURNAME.value) {
|
||||
opt.inquire("mode", { o, def -> PinyinCore.parseMode(o) ?: def }, DefaultOptions.MODE.value) -> {
|
||||
PinyinCore.surnamePinyin(hans, opt)
|
||||
}
|
||||
else -> {
|
||||
val pinyinList = mutableListOf<List<String>>()
|
||||
for (words in phrases) {
|
||||
val firstCharCode = words.codePointAt(0)
|
||||
if (fromCodePointInternal(firstCharCode) != null) {
|
||||
if (nonHans.isNotEmpty()) {
|
||||
pinyinList.add(listOf(nonHans))
|
||||
nonHans = ""
|
||||
}
|
||||
|
||||
val newPinyinList = when (words.length) {
|
||||
1 -> PinyinCore.convert(words, opt)
|
||||
else -> phrasePinyin(words, opt)
|
||||
}
|
||||
|
||||
if (opt.inquire("group", ::coerceBoolean, false)) {
|
||||
pinyinList.add(groupPhrases(newPinyinList))
|
||||
} else {
|
||||
pinyinList.addAll(newPinyinList)
|
||||
}
|
||||
} else {
|
||||
nonHans += words
|
||||
}
|
||||
}
|
||||
if (nonHans.isNotEmpty()) {
|
||||
pinyinList.add(listOf(nonHans))
|
||||
}
|
||||
pinyinList
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun `as`(args: Array<out Any?>): String = ensureArgumentsOnlyOne(args) { o ->
|
||||
convertToTonePinyin(coerceString(o, ""))
|
||||
fun compare(args: Array<out Any?>): String = ensureArgumentsLengthInRange(args, 1..2) { argList ->
|
||||
""
|
||||
}
|
||||
|
||||
private fun convertToTonePinyin(input: String): String {
|
||||
val regex = Regex("(üe|u:e|ve|ue|ang|eng|ing|ong|ai|ei|ui|ao|ou|iu|ie|er|an|en|in|un|ün|u:n|vn|[aoeiuüv])([0-4])")
|
||||
return regex.replace(input) { matchResult ->
|
||||
val pinyinBase = matchResult.groupValues[1]
|
||||
val toneNumber = matchResult.groupValues[2]
|
||||
pinyinToneMap[pinyinBase + toneNumber] ?: matchResult.value
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun compact(args: Array<out Any?>): String = ensureArgumentsLengthInRange(args, 1..2) { argList ->
|
||||
""
|
||||
}
|
||||
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun simple(args: Array<out Any?>): String = ensureArgumentsLengthInRange(args, 1..3) { argList ->
|
||||
val (str, enableNumericTone, enableSegment) = argList
|
||||
simpleRhino(coerceString(str, ""), coerceBoolean(enableNumericTone, false), coerceBoolean(enableSegment, false))
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun simpleRhino(s: String, enableNumericTone: Boolean = false, enableSegment: Boolean = false): String {
|
||||
return convertRhino(s, newNativeObject().also {
|
||||
it.defineProp("style", if (enableNumericTone) PinyinStyle.TONE2 else PinyinStyle.NORMAL)
|
||||
it.defineProp("segment", enableSegment)
|
||||
}).map { it.firstOrNull() ?: emptyList<String>() }.joinToString("")
|
||||
}
|
||||
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun fromCodePoint(args: Array<out Any?>): String? = ensureArgumentsOnlyOne(args) { o ->
|
||||
fromCodePointInternal(coerceIntNumber(o))
|
||||
}
|
||||
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun fromPhrase(args: Array<out Any?>): NativeArray = ensureArgumentsOnlyOne(args) { o ->
|
||||
fromPhraseInternal(coerceString(o)).map { it.toNativeArray() }.toNativeArray()
|
||||
}
|
||||
|
||||
internal fun fromCodePointInternal(codePoint: Int): String? = charsDictDatabase.let { db ->
|
||||
db.query(
|
||||
"Dict",
|
||||
arrayOf("Pinyin"),
|
||||
"CodePoint = ?",
|
||||
arrayOf(codePoint.toString()),
|
||||
null,
|
||||
null,
|
||||
null
|
||||
).use { cursor ->
|
||||
when {
|
||||
cursor.moveToFirst() -> cursor.getString(cursor.getColumnIndexOrThrow("Pinyin"))
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun fromPhraseInternal(phrase: String): List<List<String>> = phrasesDictDatabase.let { db ->
|
||||
val cursor = db.query(
|
||||
"PhrasesDict",
|
||||
arrayOf("Pinyin", "OrderIndex"),
|
||||
"Word = ?",
|
||||
arrayOf(phrase),
|
||||
null,
|
||||
null,
|
||||
"OrderIndex ASC",
|
||||
)
|
||||
|
||||
val result = mutableListOf<MutableList<String>>()
|
||||
cursor.use {
|
||||
while (it.moveToNext()) {
|
||||
val pinyin = it.getString(it.getColumnIndexOrThrow("Pinyin"))
|
||||
val orderIndex = it.getInt(it.getColumnIndexOrThrow("OrderIndex"))
|
||||
while (result.size < orderIndex) {
|
||||
result.add(mutableListOf())
|
||||
}
|
||||
result[orderIndex - 1].add(pinyin)
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
private fun segment(hans: String): List<String> {
|
||||
return JiebaSegmenter(globalContext).cutSmall(hans, 4)
|
||||
}
|
||||
|
||||
private fun phrasePinyin(phrase: String, options: NativeObject): List<List<String>> {
|
||||
val phrasePinyinList = fromPhraseInternal(phrase)
|
||||
return when {
|
||||
phrasePinyinList.isNotEmpty() -> {
|
||||
val style = options.inquire("style", { o, def -> parseStyle(o) ?: def }, DefaultOptions.STYLE.value)
|
||||
phrasePinyinList.map { item ->
|
||||
if (options.inquire("heteronym", ::coerceBoolean, DefaultOptions.HETERONYM)) {
|
||||
item.map { pyItem -> PinyinCore.toFixed(pyItem, style) }.toMutableList()
|
||||
} else {
|
||||
mutableListOf(PinyinCore.toFixed(item[0], style))
|
||||
}
|
||||
}.toMutableList()
|
||||
}
|
||||
else -> PinyinCore.convert(phrase, options)
|
||||
}
|
||||
}
|
||||
|
||||
private fun groupPhrases(phrases: List<List<String>>): List<String> {
|
||||
return when (phrases.size) {
|
||||
1 -> phrases[0]
|
||||
else -> Util.combo(phrases)
|
||||
}
|
||||
}
|
||||
|
||||
private fun groupChineseAndNonChinese(input: String): List<String> {
|
||||
if (input.isEmpty()) return emptyList()
|
||||
|
||||
val result = mutableListOf<String>()
|
||||
val chineseRegex = "\\p{IsHan}".toRegex() // 匹配中文字符的正则
|
||||
var tempGroup = StringBuilder()
|
||||
var isLastChinese = chineseRegex.matches(input[0].toString()) // 判断第一个字符是否中文
|
||||
|
||||
for (char in input) {
|
||||
val isChinese = chineseRegex.matches(char.toString())
|
||||
// 如果字符类型(中文或非中文)发生切换,保存当前分组
|
||||
if (isChinese != isLastChinese) {
|
||||
result.add(tempGroup.toString()) // 添加当前分组
|
||||
tempGroup = StringBuilder() // 重置分组
|
||||
}
|
||||
tempGroup.append(char) // 将字符添加到当前分组
|
||||
isLastChinese = isChinese // 更新当前字符类型
|
||||
}
|
||||
// 添加最后一个分组
|
||||
if (tempGroup.isNotEmpty()) {
|
||||
result.add(tempGroup.toString())
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
package org.autojs.autojs.runtime.api.augment.pinyin
|
||||
|
||||
import org.autojs.autojs.extension.AnyExtensions.isJsNullish
|
||||
import org.autojs.autojs.extension.AnyExtensions.jsUnwrapped
|
||||
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceBoolean
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceString
|
||||
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||
import org.mozilla.javascript.NativeObject
|
||||
import java.util.regex.Pattern
|
||||
|
||||
object PinyinCore {
|
||||
|
||||
private val SURNAME = Dict.SURNAME
|
||||
private val COMPOUND_SURNAME = Dict.COMPOUND_SURNAME
|
||||
|
||||
// 声母表
|
||||
private val INITIALS = arrayOf(
|
||||
"b", "p", "m", "f", "d", "t", "n", "l",
|
||||
"g", "k", "h", "j", "q", "x",
|
||||
"zh", "ch", "sh", "r", "z", "c", "s",
|
||||
)
|
||||
|
||||
// 韵母表
|
||||
private val FINALS = arrayOf(
|
||||
"a", "o", "e", "i", "u", "v",
|
||||
"ai", "ei", "ui", "ao", "ou", "iu", "ie", "ve", "er",
|
||||
"an", "en", "in", "un", "vn",
|
||||
"ang", "eng", "ing", "ong",
|
||||
)
|
||||
|
||||
// 带声调字符
|
||||
private val PHONETIC_SYMBOL = Dict.PHONETIC_SYMBOL
|
||||
private val RE_PHONETIC_SYMBOL = Pattern.compile("([${PHONETIC_SYMBOL.keys.joinToString("")}])").toRegex()
|
||||
private val RE_TONE2 = Regex("([aeoiuvnm])([0-4])$")
|
||||
|
||||
/**
|
||||
* @param hansArg 要转为拼音的目标字符串 (汉字).
|
||||
* @param options 可选, 用于指定拼音风格, 是否启用多音字.
|
||||
* @return 返回的拼音列表.
|
||||
*/
|
||||
fun convert(hansArg: String, options: NativeObject = newNativeObject()): MutableList<List<String>> {
|
||||
val pinyinList = mutableListOf<List<String>>()
|
||||
val hans = coerceString(hansArg, "").trim()
|
||||
|
||||
if (hans.isNotEmpty()) {
|
||||
var nonHans = ""
|
||||
|
||||
when (PinyinMode.SURNAME.value) {
|
||||
options.inquire("mode", { o, def -> parseMode(o) ?: def }, DefaultOptions.MODE.value) -> {
|
||||
pinyinList.addAll(surnamePinyin(hans, options))
|
||||
}
|
||||
else -> hans.forEach { char ->
|
||||
when {
|
||||
Pinyin.fromCodePointInternal(char.code) != null -> {
|
||||
// 拼音转换
|
||||
if (nonHans.isNotEmpty()) {
|
||||
pinyinList.add(listOf(nonHans))
|
||||
nonHans = ""
|
||||
}
|
||||
pinyinList.add(singlePinyin(char.toString(), options))
|
||||
}
|
||||
else -> nonHans += char
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nonHans.isNotEmpty()) pinyinList.add(listOf(nonHans))
|
||||
}
|
||||
|
||||
return pinyinList
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较两个汉字转成拼音后的排序顺序, 可以用作默认的拼音排序算法.
|
||||
*
|
||||
* @param hanA 汉字字符串 A.
|
||||
* @param hanB 汉字字符串 B.
|
||||
* @return -1, 0 或 1.
|
||||
*/
|
||||
fun compare(hanA: String, hanB: String): Int {
|
||||
return coerceString(convert(hanA)).compareTo(coerceString(convert(hanB)))
|
||||
}
|
||||
|
||||
fun compact(arr: List<List<String>>) = Util.compact(arr)
|
||||
|
||||
/**
|
||||
* 单字拼音转换.
|
||||
*
|
||||
* @param han 单个汉字.
|
||||
* @param options 选项.
|
||||
* @return 返回拼音列表, 多音字会有多个拼音项.
|
||||
*/
|
||||
private fun singlePinyin(han: String, options: NativeObject): List<String> {
|
||||
require(han.isNotEmpty()) { "Argument han must not be empty" }
|
||||
val hanCode = han.first().code
|
||||
val consulted = Pinyin.fromCodePointInternal(hanCode)
|
||||
val pinyinList = consulted?.split(",") ?: return listOf(han.first().toString())
|
||||
val style = options.inquire("style", { o, def -> parseStyle(o) ?: def }, DefaultOptions.STYLE.value)
|
||||
return when {
|
||||
options.inquire("heteronym", ::coerceBoolean, DefaultOptions.HETERONYM) -> {
|
||||
pinyinList.map { toFixed(it, style) }.distinct()
|
||||
}
|
||||
else -> listOf(toFixed(pinyinList.first(), style))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 单姓处理, 将单个姓氏转换为拼音.
|
||||
*
|
||||
* @param hans 姓氏字符串.
|
||||
* @param options 转换选项 (包括风格、多音字选项等).
|
||||
* @return 转换后的拼音列表.
|
||||
*/
|
||||
private fun singleSurname(hans: String, options: NativeObject): List<List<String>> {
|
||||
val result = mutableListOf<List<String>>()
|
||||
|
||||
// 遍历所有汉字
|
||||
hans.forEach { char ->
|
||||
val word = char.toString()
|
||||
when {
|
||||
// 如果是已知的姓氏, 从预定义数据中获取拼音, 并格式化
|
||||
SURNAME.containsKey(word) -> SURNAME[word]?.map { toFixedList(it, options) }?.let { surnamePinyin ->
|
||||
result.addAll(surnamePinyin)
|
||||
}
|
||||
// 如果是未知姓氏, 则按一般规则转换为拼音
|
||||
else -> result.add(singlePinyin(word, options))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 姓名转换为拼音.
|
||||
*/
|
||||
fun surnamePinyin(hans: String, options: NativeObject): List<List<String>> {
|
||||
return compoundSurname(hans, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 复姓处理, 将复姓转换为拼音.
|
||||
*
|
||||
* @param hans 包含复姓的字符串.
|
||||
* @param options 转换选项 (包含拼音风格等).
|
||||
* @return 转换后的拼音列表.
|
||||
*/
|
||||
private fun compoundSurname(hans: String, options: NativeObject): List<List<String>> {
|
||||
val len = hans.length
|
||||
var prefixIndex = 0
|
||||
val result = mutableListOf<List<String>>()
|
||||
|
||||
var i = 0
|
||||
while (i < len) {
|
||||
// 获取两个连续字符, 检测是否是复姓
|
||||
val twoWords = hans.substring(i, (i + 2).coerceAtMost(len))
|
||||
|
||||
if (!COMPOUND_SURNAME.containsKey(twoWords)) {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果前缀内容存在 (非复姓部分), 处理非复姓部分
|
||||
if (prefixIndex < i) {
|
||||
val nonCompoundPart = hans.substring(prefixIndex, i)
|
||||
result.addAll(singleSurname(nonCompoundPart, options)) // 调用单姓处理函数
|
||||
}
|
||||
|
||||
// 处理复姓部分, 并格式化为指定风格
|
||||
COMPOUND_SURNAME[twoWords]?.map { toFixedList(it, options) }?.let { compoundPart ->
|
||||
result.addAll(compoundPart)
|
||||
}
|
||||
|
||||
// 跳过复姓的两个字
|
||||
i += 2
|
||||
prefixIndex = i
|
||||
}
|
||||
|
||||
// 处理复姓最后剩下的部分 (即非复姓部分)
|
||||
if (prefixIndex < len) {
|
||||
val remaining = hans.substring(prefixIndex, len)
|
||||
result.addAll(singleSurname(remaining, options))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化拼音风格.
|
||||
*
|
||||
* @param pinyin TONE 风格的拼音.
|
||||
* @param style 目标转换的拼音风格.
|
||||
* @return 转换后的拼音.
|
||||
*/
|
||||
internal fun toFixed(pinyin: String, style: Int): String = when (style) {
|
||||
PinyinStyle.NORMAL.value -> pinyin.replace(RE_PHONETIC_SYMBOL) { matchResult ->
|
||||
PHONETIC_SYMBOL[matchResult.groupValues[1]]?.replace(RE_TONE2, "$1") ?: matchResult.value
|
||||
}
|
||||
PinyinStyle.INITIALS.value -> initials(pinyin)
|
||||
PinyinStyle.FIRST_LETTER.value -> pinyin.first().toString()
|
||||
PinyinStyle.TONE.value -> pinyin
|
||||
PinyinStyle.TONE2.value -> {
|
||||
var tone = ""
|
||||
val py = pinyin.replace(RE_PHONETIC_SYMBOL) { matchResult ->
|
||||
PHONETIC_SYMBOL[matchResult.groupValues[1]]?.let { s ->
|
||||
s.replace(RE_TONE2, "$2").also { tone = it }
|
||||
s.replace(RE_TONE2, "$1")
|
||||
} ?: matchResult.value
|
||||
}
|
||||
py + tone
|
||||
}
|
||||
PinyinStyle.TO3NE.value -> pinyin.replace(RE_PHONETIC_SYMBOL) { matchResult ->
|
||||
PHONETIC_SYMBOL[matchResult.groupValues[1]] ?: matchResult.value
|
||||
}
|
||||
else -> pinyin
|
||||
}
|
||||
|
||||
private fun toFixedList(items: List<String>, options: NativeObject): List<String> {
|
||||
val style = options.inquire("style", { o, def -> parseStyle(o) ?: def }, DefaultOptions.STYLE.value)
|
||||
return items.map { toFixed(it, style) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化拼音为声母 (Initials) 形式.
|
||||
*/
|
||||
private fun initials(pinyin: String) = INITIALS.find { pinyin.startsWith(it) } ?: ""
|
||||
|
||||
internal fun parseMode(o: Any): Int? {
|
||||
val obj = o.jsUnwrapped()
|
||||
return when {
|
||||
obj.isJsNullish() -> null
|
||||
obj is PinyinMode -> obj.value
|
||||
obj is Int -> {
|
||||
require(PinyinMode.entries.any { it.value == obj }) { "Invalid mode constant: $obj" }
|
||||
obj
|
||||
}
|
||||
else -> coerceString(obj, "").uppercase().let { name ->
|
||||
PinyinMode.entries.find { it.name == name }?.value ?: throw IllegalArgumentException("Invalid mode name: $obj")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun parseStyle(o: Any): Int? {
|
||||
val obj = o.jsUnwrapped()
|
||||
return when {
|
||||
obj.isJsNullish() -> null
|
||||
obj is PinyinStyle -> obj.value
|
||||
obj is Int -> {
|
||||
require(PinyinStyle.entries.any { it.value == obj }) { "Invalid style constant: $obj" }
|
||||
obj
|
||||
}
|
||||
else -> coerceString(obj, "").uppercase().let { name ->
|
||||
PinyinStyle.entries.find { it.name == name }?.value ?: throw IllegalArgumentException("Invalid style name: $obj")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class PinyinStyle(val value: Int) {
|
||||
NORMAL(0), // 普通风格, 不带声调
|
||||
TONE(1), // 标准风格, 声调在韵母上
|
||||
TONE2(2), // 数字形式标记声调
|
||||
TO3NE(5), // 数字方式, 声母后加声调
|
||||
INITIALS(3), // 仅保留声母
|
||||
FIRST_LETTER(4), // 仅保留首字母
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
enum class PinyinMode(val value: Int) {
|
||||
NORMAL(0), // 普通模式
|
||||
SURNAME(1), // 姓氏模式
|
||||
PLACE_NAME(2), // 地名模式
|
||||
PLACENAME(2), // 地名模式 (兼容)
|
||||
}
|
||||
|
||||
object DefaultOptions {
|
||||
val MODE = PinyinMode.NORMAL // 默认模式
|
||||
val STYLE = PinyinStyle.TONE // 默认风格
|
||||
const val SEGMENT: Boolean = false // 是否分词
|
||||
const val HETERONYM: Boolean = false // 是否允许多音字
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.autojs.autojs.runtime.api.augment.pinyin
|
||||
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceString
|
||||
|
||||
/**
|
||||
* 工具类 Util, 用于实现拼音转换时辅助功能.
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
object Util {
|
||||
|
||||
/**
|
||||
* 合并二维字符串数组为一维字符串数组.
|
||||
*
|
||||
* @param arr 二维数组, 如 [["zhāo", "cháo"], ["yáng"], ["dōng"], ["shēng"]]
|
||||
* @return 合并后的字符串数组, 一维结果, 如 ["zhāoyáng", "cháoyáng", "dōng", "shēng"]
|
||||
*/
|
||||
fun combo(arr: List<List<String>>): List<String> = when {
|
||||
arr.size <= 1 -> arr.firstOrNull() ?: emptyList()
|
||||
else -> {
|
||||
var result = combo2array(arr[0], arr[1])
|
||||
for (i in 2 until arr.size) {
|
||||
result = combo2array(result, arr[i])
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组合两个拼音数组为一维字符串数组.
|
||||
*
|
||||
* @param a1 第一个拼音数组, 如 ["zhāo", "cháo"]
|
||||
* @param a2 第二个拼音数组, 如 ["yáng"]
|
||||
* @return 组合后的一维字符串数组, 如 ["zhāoyáng", "cháoyáng"]
|
||||
*/
|
||||
private fun combo2array(a1: List<String>, a2: List<String>): List<String> {
|
||||
return when {
|
||||
a1.isEmpty() -> a2
|
||||
a2.isEmpty() -> a1
|
||||
else -> a1.flatMap { item1 -> a2.map { item2 -> item1 + item2 } }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并多个拼音数组, 形成一个新的二维数组.
|
||||
* 每两个拼音元素形成一个元组数组.
|
||||
*
|
||||
* @param arr 二维数组(每组拼音数组)
|
||||
* @return 合并后的二维拼音数组, 如 [[hai, qian], [huan, qian]]
|
||||
*/
|
||||
fun compact(arr: List<List<String>>): List<List<String>> = when {
|
||||
arr.isEmpty() -> emptyList()
|
||||
arr.size == 1 -> arr.map { listOf(it).flatten() }
|
||||
else -> {
|
||||
var result = compact2array(arr[0], arr[1])
|
||||
for (i in 2 until arr.size) {
|
||||
result = compact2array(result, arr[i])
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 组合两个拼音数组, 形成一个新的二维数组.
|
||||
*
|
||||
* @param a1 第一个拼音数组 eg: ["hai", "huan"] / [["hai"], ["huan"]]
|
||||
* @param a2 第二个拼音数组 eg: ["qian"]
|
||||
* @return 组合后的二维数组, 如 [["hai", "qian"], ["huan", "qian"]]
|
||||
*/
|
||||
private fun compact2array(a1: List<Any>, a2: List<String>): List<List<String>> = when {
|
||||
a1.isEmpty() -> listOf(a2)
|
||||
a2.isEmpty() -> a1.map { item1 ->
|
||||
when (item1) {
|
||||
is List<*> -> item1.map { coerceString(it) }
|
||||
else -> listOf(item1.toString())
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
val result = mutableListOf<List<String>>()
|
||||
a1.forEach { item1 ->
|
||||
val list1 = when (item1) {
|
||||
is List<*> -> item1.map { coerceString(it) }
|
||||
else -> listOf(coerceString(item1))
|
||||
}
|
||||
a2.mapTo(result) { list1 + it }
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
package org.autojs.autojs.runtime.api.augment.pinyin4j
|
||||
|
||||
import net.sourceforge.pinyin4j.PinyinHelper
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType.LOWERCASE
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType.UPPERCASE
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType.WITHOUT_TONE
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType.WITH_TONE_MARK
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType.WITH_TONE_NUMBER
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType.WITH_U_AND_COLON
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType.WITH_U_UNICODE
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType.WITH_V
|
||||
import org.autojs.autojs.annotation.RhinoSingletonFunctionInterface
|
||||
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
|
||||
import org.autojs.autojs.runtime.api.augment.Augmentable
|
||||
import org.autojs.autojs.runtime.api.augment.Invokable
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceString
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceStringUppercase
|
||||
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||
import org.mozilla.javascript.Context
|
||||
import org.mozilla.javascript.NativeObject
|
||||
|
||||
object Pinyin4j : Augmentable(), Invokable {
|
||||
|
||||
private const val DEFAULT_SEPARATOR = ""
|
||||
|
||||
private const val DEFAULT_CASE_TYPE_STRING = "LOWERCASE"
|
||||
private val DEFAULT_CASE_TYPE = LOWERCASE
|
||||
|
||||
private const val DEFAULT_TONE_TYPE_STRING = "WITHOUT_TONE"
|
||||
private val DEFAULT_TONE_TYPE = WITHOUT_TONE
|
||||
|
||||
private const val DEFAULT_V_CHAR_TYPE_STRING = "WITH_V"
|
||||
private val DEFAULT_V_CHAR_TYPE = WITH_V
|
||||
|
||||
private val pinyinToneMap = mapOf(
|
||||
// 单韵母
|
||||
"a1" to "ā", "a2" to "á", "a3" to "ǎ", "a4" to "à", "a0" to "a",
|
||||
"o1" to "ō", "o2" to "ó", "o3" to "ǒ", "o4" to "ò", "o0" to "o",
|
||||
"e1" to "ē", "e2" to "é", "e3" to "ě", "e4" to "è", "e0" to "e",
|
||||
"i1" to "ī", "i2" to "í", "i3" to "ǐ", "i4" to "ì", "i0" to "i",
|
||||
"u1" to "ū", "u2" to "ú", "u3" to "ǔ", "u4" to "ù", "u0" to "u",
|
||||
"ü1" to "ǖ", "ü2" to "ǘ", "ü3" to "ǚ", "ü4" to "ǜ", "ü0" to "ü",
|
||||
"v1" to "ǖ", "v2" to "ǘ", "v3" to "ǚ", "v4" to "ǜ", "v0" to "ü",
|
||||
"u:1" to "ǖ", "u:2" to "ǘ", "u:3" to "ǚ", "u:4" to "ǜ", "u:0" to "ü",
|
||||
|
||||
// 复韵母 - 普通
|
||||
"ai1" to "āi", "ai2" to "ái", "ai3" to "ǎi", "ai4" to "ài", "ai0" to "ai",
|
||||
"ei1" to "ēi", "ei2" to "éi", "ei3" to "ěi", "ei4" to "èi", "ei0" to "ei",
|
||||
"ui1" to "uī", "ui2" to "uí", "ui3" to "uǐ", "ui4" to "uì", "ui0" to "ui",
|
||||
"ao1" to "āo", "ao2" to "áo", "ao3" to "ǎo", "ao4" to "ào", "ao0" to "ao",
|
||||
"ou1" to "ōu", "ou2" to "óu", "ou3" to "ǒu", "ou4" to "òu", "ou0" to "ou",
|
||||
"iu1" to "iū", "iu2" to "iú", "iu3" to "iǔ", "iu4" to "iù", "iu0" to "iu",
|
||||
"ie1" to "iē", "ie2" to "ié", "ie3" to "iě", "ie4" to "iè", "ie0" to "ie",
|
||||
"üe1" to "üē", "üe2" to "üé", "üe3" to "üě", "üe4" to "üè", "üe0" to "üe",
|
||||
"u:e1" to "üē", "u:e2" to "üé", "u:e3" to "üě", "u:e4" to "üè", "u:e0" to "üe",
|
||||
"ve1" to "üē", "ve2" to "üé", "ve3" to "üě", "ve4" to "üè", "ve0" to "üe",
|
||||
|
||||
// 复韵母 - 特殊
|
||||
"er1" to "ēr", "er2" to "ér", "er3" to "ěr", "er4" to "èr", "er0" to "er",
|
||||
|
||||
// 复韵母 - 前鼻韵母
|
||||
"an1" to "ān", "an2" to "án", "an3" to "ǎn", "an4" to "àn", "an0" to "an",
|
||||
"en1" to "ēn", "en2" to "én", "en3" to "ěn", "en4" to "èn", "en0" to "en",
|
||||
"in1" to "īn", "in2" to "ín", "in3" to "ǐn", "in4" to "ìn", "in0" to "in",
|
||||
"un1" to "ūn", "un2" to "ún", "un3" to "ǔn", "un4" to "ùn", "un0" to "un",
|
||||
"ün1" to "ǖn", "ün2" to "ǘn", "ün3" to "ǚn", "ün4" to "ǜn", "ün0" to "ün",
|
||||
"u:n1" to "ǖn", "u:n2" to "ǘn", "u:n3" to "ǚn", "u:n4" to "ǜn", "u:n0" to "ün",
|
||||
"vn1" to "ǖn", "vn2" to "ǘn", "vn3" to "ǚn", "vn4" to "ǜn", "vn0" to "ün",
|
||||
|
||||
// 复韵母 - 后鼻韵母
|
||||
"ang1" to "āng", "ang2" to "áng", "ang3" to "ǎng", "ang4" to "àng", "ang0" to "ang",
|
||||
"eng1" to "ēng", "eng2" to "éng", "eng3" to "ěng", "eng4" to "èng", "eng0" to "eng",
|
||||
"ing1" to "īng", "ing2" to "íng", "ing3" to "ǐng", "ing4" to "ìng", "ing0" to "ing",
|
||||
"ong1" to "ōng", "ong2" to "óng", "ong3" to "ǒng", "ong4" to "òng", "ong0" to "ong"
|
||||
)
|
||||
|
||||
override val selfAssignmentFunctions = listOf(
|
||||
::`as`.name,
|
||||
::of.name,
|
||||
)
|
||||
|
||||
@RhinoSingletonFunctionInterface
|
||||
override fun invoke(args: Array<out Any?>): String = ensureArgumentsLengthInRange(args, 1..2) { argList ->
|
||||
of(argList)
|
||||
}
|
||||
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun of(args: Array<out Any?>): String = ensureArgumentsLengthInRange(args, 1..2) { argList ->
|
||||
val (string, options) = argList
|
||||
|
||||
val str = coerceString(string, "").takeIf { it.isNotEmpty() } ?: return@ensureArgumentsLengthInRange ""
|
||||
var separator = DEFAULT_SEPARATOR
|
||||
val opt = when (options) {
|
||||
is String -> newNativeObject().also { separator = options }
|
||||
is NativeObject -> options
|
||||
else -> newNativeObject()
|
||||
}
|
||||
|
||||
separator = opt.inquire(listOf("separator", "sep"), ::coerceString, separator)
|
||||
|
||||
val caseType = when (val case = opt.inquire(listOf("case", "caseType"))) {
|
||||
is HanyuPinyinCaseType -> case
|
||||
else -> when (coerceStringUppercase(case, DEFAULT_CASE_TYPE_STRING)) {
|
||||
"LOWERCASE", "LOW", "L", "0" -> LOWERCASE
|
||||
"UPPERCASE", "UP", "U", "1" -> UPPERCASE
|
||||
else -> throw IllegalArgumentException("Invalid case type: ${Context.toString(case)}")
|
||||
}
|
||||
}
|
||||
val toneType = when (val tone = opt.inquire(listOf("tone", "toneType"))) {
|
||||
is HanyuPinyinToneType -> tone
|
||||
else -> when (coerceStringUppercase(tone, DEFAULT_TONE_TYPE_STRING)) {
|
||||
"WITH_TONE_NUMBER", "WITH_NUMBER", "NUMBER", "NUM" -> WITH_TONE_NUMBER
|
||||
"WITHOUT_TONE", "NO_TONE", "NO", "FALSE", "0" -> WITHOUT_TONE
|
||||
"WITH_TONE_MARK", "WITH_MARK", "MARK", "TRUE", "1" -> WITH_TONE_MARK
|
||||
else -> throw IllegalArgumentException("Invalid tone type: ${Context.toString(tone)}")
|
||||
}
|
||||
}
|
||||
val vCharType = when (val vChar = opt.inquire(listOf("v", "vChar", "vCharType"))) {
|
||||
is HanyuPinyinVCharType -> vChar
|
||||
else -> when (coerceStringUppercase(vChar, if (toneType == WITH_TONE_MARK) "WITH_U_UNICODE" else DEFAULT_V_CHAR_TYPE_STRING)) {
|
||||
"WITH_U_AND_COLON", "U_AND_COLON", "U_COLON", "U:" -> WITH_U_AND_COLON
|
||||
"WITH_V", "V" -> WITH_V
|
||||
"WITH_U_UNICODE", "U_UNICODE", "UNICODE", "Ü" -> WITH_U_UNICODE
|
||||
else -> throw IllegalArgumentException("Invalid v char type: ${Context.toString(vChar)}")
|
||||
}
|
||||
}
|
||||
ofRhino(str, separator, caseType, toneType, vCharType)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun ofRhino(
|
||||
str: String,
|
||||
separator: String = DEFAULT_SEPARATOR,
|
||||
caseType: HanyuPinyinCaseType = DEFAULT_CASE_TYPE,
|
||||
toneType: HanyuPinyinToneType = DEFAULT_TONE_TYPE,
|
||||
vCharType: HanyuPinyinVCharType = DEFAULT_V_CHAR_TYPE,
|
||||
): String {
|
||||
val format = HanyuPinyinOutputFormat().also {
|
||||
it.caseType = caseType
|
||||
it.toneType = toneType
|
||||
it.vCharType = vCharType
|
||||
}
|
||||
|
||||
val pinyinResult = StringBuilder()
|
||||
|
||||
str.forEach { ch ->
|
||||
val pinyin4j = when (ch) {
|
||||
in '\u4E00'..'\u9FA5' -> {
|
||||
PinyinHelper.toHanyuPinyinStringArray(ch, format)?.firstOrNull() ?: ""
|
||||
}
|
||||
else -> ch.toString()
|
||||
}
|
||||
pinyinResult.append(pinyin4j).append(separator)
|
||||
}
|
||||
|
||||
return pinyinResult.toString().trim()
|
||||
}
|
||||
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun `as`(args: Array<out Any?>): String = ensureArgumentsOnlyOne(args) { o ->
|
||||
convertToTonePinyin(coerceString(o, ""))
|
||||
}
|
||||
|
||||
private fun convertToTonePinyin(input: String): String {
|
||||
val regex = Regex("(üe|u:e|ve|ue|ang|eng|ing|ong|ai|ei|ui|ao|ou|iu|ie|er|an|en|in|un|ün|u:n|vn|[aoeiuüv])([0-4])")
|
||||
return regex.replace(input) { matchResult ->
|
||||
val pinyinBase = matchResult.groupValues[1]
|
||||
val toneNumber = matchResult.groupValues[2]
|
||||
pinyinToneMap[pinyinBase + toneNumber] ?: matchResult.value
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -161,7 +161,7 @@ class UI(private val scriptRuntime: ScriptRuntime) : AugmentableProxy(scriptRunt
|
||||
val key = coerceString(keyArg)
|
||||
value?.let { mProperties[key] = it } ?: mProperties.remove(key)
|
||||
}, NOT_CONSTRUCTABLE))
|
||||
}, PERMANENT or READONLY)
|
||||
}, READONLY or PERMANENT)
|
||||
}
|
||||
|
||||
@Suppress("SameReturnValue")
|
||||
@@ -599,11 +599,11 @@ class UI(private val scriptRuntime: ScriptRuntime) : AugmentableProxy(scriptRunt
|
||||
private fun initWidgetConstructor(ctor: BaseFunction) {
|
||||
val prototype = ctor.prop("prototype") as? ScriptableObject ?: newNativeObject()
|
||||
assignWidgetProperties(prototype)
|
||||
ctor.defineProp("prototype", prototype, PERMANENT or DONTENUM)
|
||||
ctor.defineProp("prototype", prototype, DONTENUM or PERMANENT)
|
||||
}
|
||||
|
||||
private fun assignWidgetProperties(o: ScriptableObject) {
|
||||
o.defineProperty("__attrs__", newNativeObject(), PERMANENT or DONTENUM)
|
||||
o.defineProperty("__attrs__", newNativeObject(), DONTENUM or PERMANENT)
|
||||
o.defineFunctionProperties(
|
||||
arrayOf(
|
||||
"renderInternal",
|
||||
|
||||
@@ -277,7 +277,7 @@ object Util : Augmentable() {
|
||||
else -> withRhinoContext { context ->
|
||||
val tmp = object : BaseFunction() {
|
||||
override fun call(cx: Context, scope: Scriptable, thisObj: Scriptable?, args: Array<out Any?>) = newNativeObject().also {
|
||||
it.defineProperty("constructor", d, READONLY or PERMANENT or DONTENUM)
|
||||
it.defineProperty("constructor", d, READONLY or DONTENUM or PERMANENT)
|
||||
}
|
||||
}
|
||||
tmp.construct(context, ImporterTopLevel(context), arrayOf()).also { instance ->
|
||||
@@ -718,7 +718,7 @@ object Util : Augmentable() {
|
||||
it.defineFunctionProperties(
|
||||
arrayOf("toString"),
|
||||
RegularFunction::class.java,
|
||||
READONLY or PERMANENT or DONTENUM,
|
||||
READONLY or DONTENUM or PERMANENT,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import androidx.viewpager.widget.ViewPager.SimpleOnPageChangeListener
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.huaban.analysis.jieba.CharsDictionaryDatabase
|
||||
import com.huaban.analysis.jieba.PhrasesDictionaryDatabase
|
||||
import com.huaban.analysis.jieba.WordDictionaryDatabase
|
||||
import org.autojs.autojs.AutoJs
|
||||
import org.autojs.autojs.app.FragmentPagerAdapterBuilder
|
||||
import org.autojs.autojs.app.FragmentPagerAdapterBuilder.StoredFragmentPagerAdapter
|
||||
@@ -230,12 +233,20 @@ class MainActivity : BaseActivity(), DelegateHost, HostActivity {
|
||||
|
||||
fun exitCompletely() {
|
||||
FloatyWindowManger.hideCircularMenuAndSaveState()
|
||||
|
||||
stopService(Intent(this, FloatyService::class.java))
|
||||
stopService(Intent(this, ScreenCapturerForegroundService::class.java))
|
||||
|
||||
AutoJs.instance.scriptEngineService.stopAll()
|
||||
|
||||
WordDictionaryDatabase.getInstance(this).close()
|
||||
CharsDictionaryDatabase.getInstance(this).close()
|
||||
PhrasesDictionaryDatabase.getInstance(this).close()
|
||||
|
||||
mA11yTool.stopService(false)
|
||||
mForeGroundService.stopIfNeeded()
|
||||
WrappedShizuku.onDestroy()
|
||||
|
||||
Process.killProcess(Process.myPid())
|
||||
}
|
||||
|
||||
|
||||
@@ -234,8 +234,8 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView {
|
||||
mTask = task;
|
||||
firstCharIconBinding.firstChar
|
||||
.setIcon(AutoFileSource.ENGINE.equals(mTask.getEngineName()) ? FileUtils.TYPE.AUTO.icon : FileUtils.TYPE.JAVASCRIPT.icon)
|
||||
// .setIconTextThemeColor()
|
||||
// .setStrokeThemeColor()
|
||||
.setIconTextThemeColor()
|
||||
.setStrokeThemeColor()
|
||||
.setFillTransparent();
|
||||
itemBinding.name.setText(task.getName());
|
||||
itemBinding.taskListFilePath.setText(task.getDesc());
|
||||
|
||||
@@ -56,7 +56,6 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -115,8 +114,11 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
||||
EditText mOutputPath;
|
||||
EditText mAppName;
|
||||
EditText mPackageName;
|
||||
TextInputLayout mPackageNameParent;
|
||||
EditText mVersionName;
|
||||
TextInputLayout mVersionNameParent;
|
||||
EditText mVersionCode;
|
||||
TextInputLayout mVersionCodeParent;
|
||||
ImageView mIcon;
|
||||
LinearLayout mAppConfig;
|
||||
|
||||
@@ -181,11 +183,15 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
||||
}
|
||||
return false;
|
||||
});
|
||||
mPackageNameParent = binding.packageNameParent;
|
||||
|
||||
mVersionName = binding.versionName;
|
||||
mVersionNameParent = binding.versionNameParent;
|
||||
mVersionCode = binding.versionCode;
|
||||
mVersionCodeParent = binding.versionCodeParent;
|
||||
|
||||
mIcon = binding.appIcon;
|
||||
mIcon.setVisibility(View.INVISIBLE);
|
||||
mIcon.setOnClickListener(v -> selectIcon());
|
||||
|
||||
mAppConfig = binding.appConfig;
|
||||
@@ -261,11 +267,11 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
||||
NotAskAgainDialog.Builder builder = new NotAskAgainDialog.Builder(context, key);
|
||||
builder.title(R.string.text_prompt);
|
||||
builder.content(getString(R.string.text_unable_to_build_apk_as_autojs6_does_not_include_selected_abi, abiText) + "\n\n" +
|
||||
getString(R.string.text_the_following_solutions_can_be_referred_to) + ":\n\n" +
|
||||
"- " + getString(R.string.text_download_and_install_autojs6_including_above_abi, abiText) + "\n" +
|
||||
"- " + getString(R.string.text_download_and_install_autojs6_including_all_abis) + " [" + getString(R.string.text_recommended) + "]\n\n" +
|
||||
getString(R.string.text_download_link_for_autojs6) + ":\n" +
|
||||
getString(R.string.uri_autojs6_download_link));
|
||||
getString(R.string.text_the_following_solutions_can_be_referred_to) + ":\n\n" +
|
||||
"- " + getString(R.string.text_download_and_install_autojs6_including_above_abi, abiText) + "\n" +
|
||||
"- " + getString(R.string.text_download_and_install_autojs6_including_all_abis) + " [" + getString(R.string.text_recommended) + "]\n\n" +
|
||||
getString(R.string.text_download_link_for_autojs6) + ":\n" +
|
||||
getString(R.string.uri_autojs6_download_link));
|
||||
builder.positiveText(R.string.dialog_button_dismiss);
|
||||
MaterialDialog dialog = builder.show();
|
||||
if (dialog != null) {
|
||||
@@ -360,6 +366,7 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
||||
return list.stream().anyMatch(item -> item.equalsIgnoreCase(s));
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private void setupWithSourceFile(ScriptFile file) {
|
||||
String dir = file.getParent();
|
||||
if (dir != null && dir.startsWith(getFilesDir().getPath())) {
|
||||
@@ -368,20 +375,42 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
||||
mOutputPath.setText(dir);
|
||||
mAppName.setText(file.getSimplifiedName());
|
||||
|
||||
String packageName = getString(R.string.format_default_package_name, generatePackageNameSuffix(file));
|
||||
mPackageName.setText(packageName);
|
||||
Observable.fromCallable(() -> {
|
||||
String packageNameSuffix = generatePackageNameSuffix(file);
|
||||
return getString(R.string.format_default_package_name, packageNameSuffix);
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(packageName -> {
|
||||
mPackageName.setText(packageName);
|
||||
mPackageNameParent.setHint(R.string.text_package_name);
|
||||
|
||||
SimpleVersionInfo nextVersionInfo = AppUtils.generateNextVersionInfo(packageName);
|
||||
if (nextVersionInfo != null) {
|
||||
mVersionName.setText(nextVersionInfo.versionName);
|
||||
mVersionCode.setText(nextVersionInfo.versionCodeString);
|
||||
}
|
||||
SimpleVersionInfo nextVersionInfo = AppUtils.generateNextVersionInfo(packageName);
|
||||
if (nextVersionInfo != null) {
|
||||
mVersionName.setText(nextVersionInfo.versionName);
|
||||
mVersionCode.setText(nextVersionInfo.versionCodeString);
|
||||
} else {
|
||||
mVersionName.setText(R.string.default_build_apk_version_name);
|
||||
mVersionCode.setText(R.string.default_build_apk_version_code);
|
||||
}
|
||||
mVersionNameParent.setHint(R.string.text_version_name);
|
||||
mVersionCodeParent.setHint(R.string.text_version_code);
|
||||
|
||||
Drawable iconDrawable = AppUtils.getInstalledAppIcon(packageName);
|
||||
if (iconDrawable != null) {
|
||||
mIcon.setImageDrawable(iconDrawable);
|
||||
mIsDefaultIcon = false;
|
||||
}
|
||||
Drawable iconDrawable = AppUtils.getInstalledAppIcon(packageName);
|
||||
if (iconDrawable != null) {
|
||||
mIcon.setImageDrawable(iconDrawable);
|
||||
mIsDefaultIcon = false;
|
||||
}
|
||||
mIcon.setVisibility(View.VISIBLE);
|
||||
}, throwable -> {
|
||||
mPackageName.setText(getString(R.string.format_default_package_name, file.getSimplifiedName().toLowerCase(Language.getPrefLanguage().getLocale())));
|
||||
mVersionName.setText(R.string.default_build_apk_version_name);
|
||||
mVersionCode.setText(R.string.default_build_apk_version_code);
|
||||
mPackageNameParent.setHint(R.string.text_package_name);
|
||||
mVersionNameParent.setHint(R.string.text_version_name);
|
||||
mVersionCodeParent.setHint(R.string.text_version_code);
|
||||
mIcon.setVisibility(View.VISIBLE);
|
||||
});
|
||||
|
||||
setSource(file);
|
||||
}
|
||||
@@ -389,7 +418,8 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
||||
private static String generatePackageNameSuffix(ScriptFile file) {
|
||||
String name = file.getSimplifiedName();
|
||||
if (name.matches(".*[\\u4e00-\\u9fff].*")) {
|
||||
name = Pinyin.ofRhino(name);
|
||||
// name = Pinyin4j.ofRhino(name);
|
||||
name = Pinyin.INSTANCE.simpleRhino(name, false, true);
|
||||
}
|
||||
name = name.replaceAll("\\W+", "_");
|
||||
if (name.matches("^\\d.*")) {
|
||||
@@ -461,11 +491,11 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
||||
return checkNotEmpty(mOutputPath);
|
||||
}
|
||||
return checkNotEmpty(mSourcePath)
|
||||
& checkNotEmpty(mOutputPath)
|
||||
& checkNotEmpty(mAppName)
|
||||
& checkNotEmpty(mVersionCode)
|
||||
& checkNotEmpty(mVersionName)
|
||||
& checkPackageNameValid(mPackageName);
|
||||
& checkNotEmpty(mOutputPath)
|
||||
& checkNotEmpty(mAppName)
|
||||
& checkNotEmpty(mVersionCode)
|
||||
& checkNotEmpty(mVersionName)
|
||||
& checkPackageNameValid(mPackageName);
|
||||
}
|
||||
|
||||
private boolean checkAbis() {
|
||||
@@ -482,9 +512,8 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
||||
|
||||
private boolean checkPackageNameValid(EditText editText) {
|
||||
Editable text = editText.getText();
|
||||
String hint = Objects.requireNonNull(((TextInputLayout) editText.getParent().getParent()).getHint()).toString();
|
||||
if (TextUtils.isEmpty(text)) {
|
||||
editText.setError(hint + getString(R.string.text_should_not_be_empty));
|
||||
editText.setError(getString(R.string.text_should_not_be_empty));
|
||||
return false;
|
||||
}
|
||||
if (!REGEX_PACKAGE_NAME.matcher(text).matches()) {
|
||||
@@ -495,15 +524,11 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
||||
}
|
||||
|
||||
private boolean checkNotEmpty(EditText editText) {
|
||||
if (!TextUtils.isEmpty(editText.getText()) || !editText.isShown())
|
||||
return true;
|
||||
// TODO by Stardust on Dec 8, 2017.
|
||||
// ! More beautiful ways?
|
||||
// ! zh-CN (translated by SuperMonster003 on Jul 29, 2024):
|
||||
// ! 更优雅的方式?
|
||||
String hint = Objects.requireNonNull(((TextInputLayout) editText.getParent().getParent()).getHint()).toString();
|
||||
editText.setError(hint + getString(R.string.text_should_not_be_empty));
|
||||
return false;
|
||||
if (TextUtils.isEmpty(editText.getText()) && editText.isShown()) {
|
||||
editText.setError(getString(R.string.text_should_not_be_empty));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void showHintDialogIfNeeded() {
|
||||
@@ -586,18 +611,18 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
||||
private boolean isWideCharacter(char c) {
|
||||
Character.UnicodeBlock block = Character.UnicodeBlock.of(c);
|
||||
return block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS ||
|
||||
block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A ||
|
||||
block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B ||
|
||||
block == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS ||
|
||||
block == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT ||
|
||||
block == Character.UnicodeBlock.HIRAGANA ||
|
||||
block == Character.UnicodeBlock.KATAKANA ||
|
||||
block == Character.UnicodeBlock.HANGUL_SYLLABLES ||
|
||||
block == Character.UnicodeBlock.HANGUL_JAMO ||
|
||||
block == Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO ||
|
||||
block == Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS ||
|
||||
block == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS ||
|
||||
block == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;
|
||||
block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A ||
|
||||
block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B ||
|
||||
block == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS ||
|
||||
block == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT ||
|
||||
block == Character.UnicodeBlock.HIRAGANA ||
|
||||
block == Character.UnicodeBlock.KATAKANA ||
|
||||
block == Character.UnicodeBlock.HANGUL_SYLLABLES ||
|
||||
block == Character.UnicodeBlock.HANGUL_JAMO ||
|
||||
block == Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO ||
|
||||
block == Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS ||
|
||||
block == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS ||
|
||||
block == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
@@ -156,10 +157,11 @@
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/package_name_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:hint="@string/text_package_name"
|
||||
android:hint="@string/text_package_name_with_computing"
|
||||
app:expandedHintEnabled="false">
|
||||
|
||||
<!-- @Hint by SuperMonster003 on Nov 18, 2024. -->
|
||||
@@ -188,10 +190,11 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/version_name_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:hint="@string/text_version_name"
|
||||
android:hint="@string/text_version_name_with_computing"
|
||||
app:expandedHintEnabled="false">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
@@ -199,15 +202,16 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:text="1.0.0" />
|
||||
tools:text="1.0.0" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/version_code_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:hint="@string/text_version_code"
|
||||
android:hint="@string/text_version_code_with_computing"
|
||||
app:expandedHintEnabled="false">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
@@ -215,7 +219,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="number"
|
||||
android:text="1" />
|
||||
tools:text="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
@@ -811,5 +811,8 @@
|
||||
<string name="text_write_secure_settings_description">إعدادات النظام الآمنة ، التي تحتوي على تفضيلات النظام التي يمكن أن تقرأها التطبيقات ولكن لا يُسمح لها بالكتابة.\nهذه هي لتفضيلات يجب على المستخدم تعديلها بشكل صريح من خلال واجهة المستخدم لتطبيق النظام.\nمع إذن إعدادات النظام الآمن ، يمكن للتطبيقات العادية تعديل الإعدادات الآمنة مباشرة (مثل خدمة إمكانية الوصول).</string>
|
||||
<string name="text_write_system_settings">كتابة إعدادات النظام</string>
|
||||
<string name="theme_color_default">تقصير</string>
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">اسم الحزمة (جارٍ الحساب...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">اسم الإصدار (جارٍ الحساب...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">رمز الإصدار (جارٍ الحساب...)</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -807,5 +807,8 @@
|
||||
<string name="text_write_secure_settings_description">Secure system settings, containing system preferences that applications can read but are not allowed to write.\nThese are for preferences that the user must explicitly modify through the UI of a system app.\nWith secure system settings permission, normal applications can directly modify the secure settings (such as accessibility service).</string>
|
||||
<string name="text_write_system_settings">Write system settings</string>
|
||||
<string name="theme_color_default">Default</string>
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">Package name (computing...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">Version name (computing...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">Version code (computing...)</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -810,5 +810,8 @@
|
||||
<string name="text_write_secure_settings_description">Ajustes de seguridad del sistema, que contienen preferencias del sistema que las aplicaciones pueden leer pero no pueden escribir.\nSe trata de preferencias que el usuario debe modificar explícitamente a través de la interfaz de usuario de una aplicación del sistema.\nCon el permiso de configuración segura del sistema, las aplicaciones normales pueden modificar directamente la configuración segura (como el servicio de accesibilidad).</string>
|
||||
<string name="text_write_system_settings">Escribir la configuración del sistema</string>
|
||||
<string name="theme_color_default">Por defecto</string>
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">Nombre del paquete (Calculando...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">Nombre de la versión (Calculando...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">Código de la versión (Calculando...)</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -810,5 +810,8 @@
|
||||
<string name="text_write_secure_settings_description">Paramètres de sécurité du système, contenant les préférences du système que les applications peuvent lire mais ne sont pas autorisées à écrire.\nIl s\'agit des préférences que l\'utilisateur doit explicitement modifier par le biais de l\'interface utilisateur d\'une application système.\nAvec l\'autorisation de paramètres de sécurité du système, les applications normales peuvent directement modifier les paramètres de sécurité (comme le service d\'accessibilité).</string>
|
||||
<string name="text_write_system_settings">Écrire les paramètres système</string>
|
||||
<string name="theme_color_default">Default</string>
|
||||
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">Nom du paquet (en cours de calcul...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">Nom de la version (en cours de calcul...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">Code de version (en cours de calcul...)</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -810,5 +810,8 @@
|
||||
<string name="text_write_secure_settings_description">アプリケーションが読み取ることはできるが, 書き込むことはできないシステム環境設定を含む, 安全なシステム設定です.\nこれは, ユーザーがシステムアプリのUIを通じて明示的に変更する必要がある環境設定のためのものです.\nセキュアなシステム設定を許可すると, 通常のアプリケーションはセキュアな設定 (アクセシビリティサービスなど) を直接変更できるようになります</string>
|
||||
<string name="text_write_system_settings">システム設定の書き込み</string>
|
||||
<string name="theme_color_default">デフォルト</string>
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">パッケージ名 (計算中...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">バージョン名 (計算中...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">バージョンコード (計算中...)</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -811,5 +811,8 @@
|
||||
<string name="text_write_secure_settings_description">애플리케이션이 읽을 수 있지만 쓸 수없는 시스템 환경 설정을 포함하는 보안 시스템 설정.\n이들은 사용자가 시스템 앱의 UI를 통해 명시 적으로 수정 해야하는 선호도입니다.\n보안 시스템 설정 권한을 사용하면 일반 애플리케이션이 보안 설정 (예: 접근성 서비스)을 직접 수정할 수 있습니다.</string>
|
||||
<string name="text_write_system_settings">시스템 설정을 작성하십시오</string>
|
||||
<string name="theme_color_default">기본</string>
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">패키지 이름 (계산 중...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">버전 이름 (계산 중...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">버전 코드 (계산 중...)</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -810,5 +810,8 @@
|
||||
<string name="text_write_secure_settings_description">Настройки безопасности системы, содержащие системные предпочтения, которые приложения могут читать, но не имеют права записывать.\nОни предназначены для параметров, которые пользователь должен явно изменить через пользовательский интерфейс системного приложения.\nПри наличии разрешения на безопасные системные настройки обычные приложения могут напрямую изменять безопасные настройки (например, служба доступности).</string>
|
||||
<string name="text_write_system_settings">Запись системных настроек</string>
|
||||
<string name="theme_color_default">По умолчанию</string>
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">Имя пакета (Вычисление...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">Название версии (Вычисление...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">Код версии (Вычисление...)</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -809,5 +809,8 @@
|
||||
<string name="text_write_secure_settings_description">安全設置包含應用程序可讀但不可寫入的設置選項, 這些選項只能由 UI 或系統級別應用修改.\n被授予 \"修改安全設置權限\" 後, 普通應用可直接修改上述安全設置 (例如無障礙服務).</string>
|
||||
<string name="text_write_system_settings">修改系統設置</string>
|
||||
<string name="theme_color_default">默認</string>
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">包名 (計算中...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">版本名稱 (計算中...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">版本號 (計算中...)</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -809,5 +809,8 @@
|
||||
<string name="text_write_secure_settings_description">安全設定包含應用程式可讀但不可寫入的設定選項, 這些選項只能由 UI 或系統級別應用修改.\n被授予 \"修改安全設定許可權\" 後, 普通應用可直接修改上述安全設定 (例如無障礙服務).</string>
|
||||
<string name="text_write_system_settings">修改系統設定</string>
|
||||
<string name="theme_color_default">預設</string>
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">包名 (計算中...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">版本名稱 (計算中...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">版本號 (計算中...)</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -805,5 +805,8 @@
|
||||
<string name="text_write_secure_settings_description">安全设置包含应用程序可读但不可写入的设置选项, 这些选项只能由 UI 或系统级别应用修改.\n被授予 \"修改安全设置权限\" 后, 普通应用可直接修改上述安全设置 (例如无障碍服务).</string>
|
||||
<string name="text_write_system_settings">修改系统设置</string>
|
||||
<string name="theme_color_default">默认</string>
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">包名 (计算中...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">版本名称 (计算中...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">版本号 (计算中...)</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -1030,5 +1030,10 @@
|
||||
<string name="value_app_language_english" translatable="false">EN</string>
|
||||
<string name="value_app_language_follow_system" translatable="false">Auto</string>
|
||||
<string name="value_app_language_simplified_chinese" translatable="false">ZH_CN</string>
|
||||
<string name="text_package_name_with_computing" tools:ignore="TypographyEllipsis">Package name (computing...)</string>
|
||||
<string name="text_version_name_with_computing" tools:ignore="TypographyEllipsis">Version name (computing...)</string>
|
||||
<string name="text_version_code_with_computing" tools:ignore="TypographyEllipsis">Version code (computing...)</string>
|
||||
<string name="default_build_apk_version_name" translatable="false">1.0.0</string>
|
||||
<string name="default_build_apk_version_code" translatable="false">1</string>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user