mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-20 14:19:08 +00:00
add list of known dictionaries for more convenient links
This commit is contained in:
parent
b1eb33f6e2
commit
fd95b4dc87
10 changed files with 215 additions and 3 deletions
|
@ -124,6 +124,10 @@ See [layouts.md](layouts.md#adding-new-layouts--languages) for how to add new la
|
|||
|
||||
See make-emoji-keys tool [README](tools/make-emoji-keys/README.md).
|
||||
|
||||
### Update List of Existing Dictionaries
|
||||
|
||||
See make-dict-list tool [README](tools/make-dict-list/README.md).
|
||||
|
||||
# License
|
||||
|
||||
HeliBoard (as a fork of OpenBoard) is licensed under GNU General Public License v3.0.
|
||||
|
|
85
app/src/main/assets/dictionaries_in_dict_repo.csv
Normal file
85
app/src/main/assets/dictionaries_in_dict_repo.csv
Normal file
|
@ -0,0 +1,85 @@
|
|||
main,ar,
|
||||
main,hy,
|
||||
main,as,
|
||||
main,bn,
|
||||
main,by,
|
||||
main,bg,
|
||||
main,ca,
|
||||
main,hr,
|
||||
main,cs,
|
||||
main,da,
|
||||
main,nl,
|
||||
main,en_AU,
|
||||
main,en_GB,
|
||||
main,en_US,
|
||||
emoji,en,
|
||||
main,eo,
|
||||
main,fi,
|
||||
emoji,fr,
|
||||
main,fr,
|
||||
main,gl,
|
||||
main,ka,
|
||||
main,de,
|
||||
main,gom,
|
||||
main,el,
|
||||
main,gu,
|
||||
main,he,
|
||||
main,iw,
|
||||
main,hi,
|
||||
main,hi_ZZ,
|
||||
main,hu,
|
||||
main,it,
|
||||
main,kn,
|
||||
main,ks,
|
||||
main,lv,
|
||||
main,lt,
|
||||
main,lb,
|
||||
main,mai,
|
||||
main,ml,
|
||||
main,mr,
|
||||
main,nb,
|
||||
main,or,
|
||||
main,pl,
|
||||
main,pt_BR,
|
||||
main,pt_PT,
|
||||
main,pa,
|
||||
main,ro,
|
||||
emoji,ru,
|
||||
main,ru,
|
||||
main,sa,
|
||||
main,sat,
|
||||
main,sr_ZZ,
|
||||
main,sr,
|
||||
main,sd,
|
||||
main,sl,
|
||||
main,es,
|
||||
main,sv,
|
||||
main,ta,
|
||||
main,te,
|
||||
main,tok,
|
||||
main,tcy,
|
||||
main,tr,
|
||||
main,uk,
|
||||
main,ur,
|
||||
main,af,exp
|
||||
main,ar,exp
|
||||
main,bn,exp
|
||||
main,bg,exp
|
||||
main,cs,exp
|
||||
main,en_GB,exp
|
||||
main,en_US,exp
|
||||
symbols,en,exp
|
||||
symbols,fr,exp
|
||||
main,fr,exp
|
||||
main,de_AT,exp
|
||||
main,de,exp
|
||||
main,id,exp
|
||||
main,it,exp
|
||||
main,kab,exp
|
||||
addon,ml_ZZ,exp
|
||||
main,ru,exp
|
||||
main,sk,exp
|
||||
main,es,exp
|
||||
main,uk,exp
|
||||
main,vi,exp
|
||||
|
|
|
@ -91,7 +91,7 @@ object LocaleUtils {
|
|||
* @param tested the locale to test.
|
||||
* @return a constant that measures how well the tested locale matches the reference locale.
|
||||
*/
|
||||
private fun getMatchLevel(reference: Locale, tested: Locale): Int {
|
||||
fun getMatchLevel(reference: Locale, tested: Locale): Int {
|
||||
if (reference == tested) return LOCALE_FULL_MATCH
|
||||
if (reference.toString().isEmpty()) return LOCALE_ANY_MATCH
|
||||
if (reference.language != tested.language) return LOCALE_NO_MATCH
|
||||
|
|
|
@ -268,10 +268,41 @@ class LanguageSettingsDialog(
|
|||
binding.secondaryLocales.addView(rowBinding.root)
|
||||
}
|
||||
|
||||
private fun createDictionaryText(locale: Locale, context: Context): String {
|
||||
val link = "<a href='$DICTIONARY_URL'>" + context.getString(R.string.dictionary_link_text) + "</a>"
|
||||
val message = context.getString(R.string.add_dictionary, link)
|
||||
val knownDicts = mutableListOf<String>()
|
||||
context.assets.open("dictionaries_in_dict_repo.csv").reader().forEachLine {
|
||||
if (it.isBlank()) return@forEachLine
|
||||
val (type, localeString, experimental) = it.split(",")
|
||||
// we use a locale string here because that's in the dictionaries repo
|
||||
// ideally the repo would switch to language tag, but not sure how this is handled in the dictionary header
|
||||
// further, the dicts in the dictionaries repo should be compatible with other AOSP-based keyboards
|
||||
val dictLocale = localeString.constructLocale()
|
||||
if (LocaleUtils.getMatchLevel(locale, dictLocale) < 3) return@forEachLine
|
||||
val rawDictString = "$type: ${dictLocale.getDisplayName(context.resources.configuration.locale())}"
|
||||
val dictString = if (experimental.isEmpty()) rawDictString
|
||||
else context.getString(R.string.available_dictionary_experimental, rawDictString)
|
||||
val dictBaseUrl = DICTIONARY_URL + DICTIONARY_DOWNLOAD_SUFFIX +
|
||||
if (experimental.isEmpty()) DICTIONARY_NORMAL_SUFFIX else DICTIONARY_EXPERIMENTAL_SUFFIX
|
||||
val dictLink = dictBaseUrl + type + "_" + localeString.lowercase() + ".dict"
|
||||
val fullText = "<li><a href='$dictLink'>$dictString</a></li>"
|
||||
knownDicts.add(fullText)
|
||||
}
|
||||
if (knownDicts.isEmpty()) return message
|
||||
return """
|
||||
<p>$message</p>
|
||||
<b>${context.getString(R.string.dictionary_available)}</b>
|
||||
<ul>
|
||||
${knownDicts.joinToString("\n")}
|
||||
</ul>
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
private fun fillDictionariesView() {
|
||||
binding.addDictionary.setOnClickListener {
|
||||
val link = "<a href='$DICTIONARY_URL'>" + context.getString(R.string.dictionary_link_text) + "</a>"
|
||||
val message = SpannableStringUtils.fromHtml(context.getString(R.string.add_dictionary, link))
|
||||
val messageRawText = createDictionaryText(mainLocale, context)
|
||||
val message = SpannableStringUtils.fromHtml(messageRawText)
|
||||
val dialog = Builder(context)
|
||||
.setTitle(R.string.add_new_dictionary_title)
|
||||
.setMessage(message)
|
||||
|
|
|
@ -85,3 +85,6 @@ private fun hasAnythingOtherThanExtractedMainDictionary(dir: File) =
|
|||
dir.listFiles()?.any { it.name != DictionaryInfoUtils.getExtractedMainDictFilename() } != false
|
||||
|
||||
const val DICTIONARY_URL = "https://codeberg.org/Helium314/aosp-dictionaries"
|
||||
const val DICTIONARY_DOWNLOAD_SUFFIX = "/src/branch/main/"
|
||||
const val DICTIONARY_NORMAL_SUFFIX = "dictionaries/"
|
||||
const val DICTIONARY_EXPERIMENTAL_SUFFIX = "dictionaries_experimental/"
|
||||
|
|
|
@ -547,6 +547,8 @@ New dictionary:
|
|||
<string name="add_dictionary">"Select a dictionary to add. Dictionaries in .dict format can be downloaded %s."</string>
|
||||
<!-- Title of the link to the download page inserted into messages (add_dictionary and no_dictionary_message) -->
|
||||
<string name="dictionary_link_text">"here"</string>
|
||||
<!-- Title of an item in the list of available dictionaries when the dictionary is experimental. This string will be interpreted as HTML -->
|
||||
<string name="available_dictionary_experimental">"%s (experimental)"</string>
|
||||
<!-- Text shown when dictionary file could not be read -->
|
||||
<string name="dictionary_file_error">"Error: Selected file is not a valid dictionary file"</string>
|
||||
<!-- Text shown when dictionary file is not for the selected locale -->
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
include ':app'
|
||||
include ':tools:make-emoji-keys'
|
||||
include ':tools:make-dict-list'
|
||||
|
|
5
tools/make-dict-list/README.md
Normal file
5
tools/make-dict-list/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# make-dict-list
|
||||
|
||||
This module takes care of generating a list of dictionaries available in the [dictionaries repository](https://codeberg.org/Helium314/aosp-dictionaries) for convenient linking when adding dictionaries in HeliBoard.
|
||||
|
||||
To use it, simply run `./gradlew tools:make-dict-list:makeDictList`
|
18
tools/make-dict-list/build.gradle
Normal file
18
tools/make-dict-list/build.gradle
Normal file
|
@ -0,0 +1,18 @@
|
|||
apply plugin: "java"
|
||||
apply plugin: 'kotlin'
|
||||
|
||||
ext {
|
||||
javaMainClass = "tools.dict.MakeDictList"
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
tasks.register('makeDictList', JavaExec) {
|
||||
args project.rootProject.project('app').projectDir.path + File.separator + 'src' +
|
||||
File.separator + 'main' + File.separator + 'assets'
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
main = javaMainClass
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package tools.dict
|
||||
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
|
||||
class MakeDictList {
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic fun main(args: Array<String>) {
|
||||
val readmeUrl = "https://codeberg.org/Helium314/aosp-dictionaries/raw/branch/main/README.md"
|
||||
val readmeText = URL(readmeUrl).readText()
|
||||
val fileText = doIt(readmeText)
|
||||
val targetDir = args[0]
|
||||
|
||||
File(targetDir).mkdirs()
|
||||
File("$targetDir/dictionaries_in_dict_repo.csv").writeText(fileText)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* extract dictionary list from README.md
|
||||
* output format: <localeString>,<type>,<experimental>
|
||||
* <experimental> is empty if dictionary is not experimental, no other check done
|
||||
* requires README.md to have dicts in correct "# Dictionaries" or "# Experimental dictionaries" sections
|
||||
*/
|
||||
private fun doIt(readme: String): String {
|
||||
// output format: <localeString>,<type>,<experimental>
|
||||
// experimental is empty if dictionary is not experimental, no other check done
|
||||
var mode = MODE_NOTHING
|
||||
val outLines = mutableListOf<String>()
|
||||
readme.split("\n").forEach { line ->
|
||||
if (line.startsWith("#")) {
|
||||
mode = if (line.trim() == "# Dictionaries")
|
||||
MODE_NORMAL
|
||||
else if (line.trim() == "# Experimental dictionaries")
|
||||
MODE_EXPERIMENTAL
|
||||
else
|
||||
MODE_NOTHING
|
||||
return@forEach
|
||||
}
|
||||
if (mode == MODE_NOTHING || !line.startsWith("*")) return@forEach
|
||||
val dictName = line.substringAfter("]").substringAfter("(").substringBefore(")")
|
||||
.substringAfterLast("/").substringBefore(".dict")
|
||||
val type = dictName.substringBefore("_")
|
||||
val rawLocale = dictName.substringAfter("_")
|
||||
val locale = if ("_" !in rawLocale) rawLocale
|
||||
else {
|
||||
val split = rawLocale.split("_").toMutableList()
|
||||
if (!split[1].startsWith("#"))
|
||||
split[1] = split[1].uppercase()
|
||||
split.joinToString("_")
|
||||
}
|
||||
outLines.add("$type,$locale,${if (mode == MODE_EXPERIMENTAL) "exp" else ""}")
|
||||
}
|
||||
return outLines.joinToString("\n") + "\n"
|
||||
}
|
||||
|
||||
private const val MODE_NOTHING = 0
|
||||
private const val MODE_NORMAL = 1
|
||||
private const val MODE_EXPERIMENTAL = 2
|
Loading…
Add table
Reference in a new issue