Compare commits
345 Commits
v0.3.11-be
...
v0.3.14-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a71c89d5d3 | ||
|
|
408716f4c4 | ||
|
|
005040df66 | ||
|
|
527b3b293e | ||
|
|
dec39e8bd9 | ||
|
|
eaa630b219 | ||
|
|
4217594dd4 | ||
|
|
96d01a28fb | ||
|
|
ec9f4a6654 | ||
|
|
1990916851 | ||
|
|
9ab49ff1c9 | ||
|
|
b4f08c38b3 | ||
|
|
5a375ec30f | ||
|
|
efded915c3 | ||
|
|
4bf335f4af | ||
|
|
643920c094 | ||
|
|
172eb54909 | ||
|
|
3d3d8f74c4 | ||
|
|
cf77038336 | ||
|
|
619e06be1b | ||
|
|
36dde9f7e0 | ||
|
|
58d0954fe4 | ||
|
|
17d28c9d9d | ||
|
|
46fb33b2a0 | ||
|
|
e36aa80cc0 | ||
|
|
3ce323596c | ||
|
|
abe67c2a6f | ||
|
|
5c1768a924 | ||
|
|
92086954de | ||
|
|
2b47d4a811 | ||
|
|
e977c512a7 | ||
|
|
0828c0a4db | ||
|
|
ecee7bfa56 | ||
|
|
7a0485c0dc | ||
|
|
d4ff6143f4 | ||
|
|
8aa8b30a43 | ||
|
|
019bdcae6f | ||
|
|
edfea2dbf2 | ||
|
|
eeec8e0d17 | ||
|
|
e79ab3c2e3 | ||
|
|
2719cf4930 | ||
|
|
d6d89aac43 | ||
|
|
973c738059 | ||
|
|
2345192728 | ||
|
|
dc1c71a01d | ||
|
|
b93b646d41 | ||
|
|
75354703ce | ||
|
|
7123f004e9 | ||
|
|
3dac44d326 | ||
|
|
76de7e5db9 | ||
|
|
95e0b3408d | ||
|
|
358440779f | ||
|
|
6518eebce7 | ||
|
|
e19df82147 | ||
|
|
3ec3f90d9f | ||
|
|
85452eeb10 | ||
|
|
e4520007ea | ||
|
|
63b55a9560 | ||
|
|
4dbc1ca740 | ||
|
|
06c585885e | ||
|
|
5bede68a82 | ||
|
|
1a83456d77 | ||
|
|
58d8ce96d9 | ||
|
|
5aec281e87 | ||
|
|
bcbf561887 | ||
|
|
813f300a15 | ||
|
|
a356585cf8 | ||
|
|
689881f981 | ||
|
|
d473369f37 | ||
|
|
5fcd605b7d | ||
|
|
2ea9dfee60 | ||
|
|
07ad6820cc | ||
|
|
1c8523c6dd | ||
|
|
84f682aaa7 | ||
|
|
efc03a90b5 | ||
|
|
8f3562a0c8 | ||
|
|
b15f7f68ae | ||
|
|
b646b3095b | ||
|
|
261ea5db2e | ||
|
|
ff93377459 | ||
|
|
f90befdfbe | ||
|
|
d490d6d457 | ||
|
|
3fdaa448af | ||
|
|
7f88643361 | ||
|
|
55dc817843 | ||
|
|
6e2969d8a6 | ||
|
|
9a146ba2f0 | ||
|
|
5f224806e2 | ||
|
|
77f048abda | ||
|
|
e45efc08a5 | ||
|
|
d1dd91d5c4 | ||
|
|
106ef0c417 | ||
|
|
8989b7130a | ||
|
|
0663708afb | ||
|
|
d58aba71b8 | ||
|
|
9d364f99e2 | ||
|
|
edb62f0f38 | ||
|
|
e771eaf0a4 | ||
|
|
199b5c9e67 | ||
|
|
5d121935d2 | ||
|
|
ee0677b6e5 | ||
|
|
11325e99c4 | ||
|
|
fc5a6b5af3 | ||
|
|
65d17ceea3 | ||
|
|
8a57ada148 | ||
|
|
82e07b4de3 | ||
|
|
6ca5645656 | ||
|
|
a75ff21305 | ||
|
|
a7b00494e5 | ||
|
|
a0de409878 | ||
|
|
3f0944906d | ||
|
|
79ef5445a1 | ||
|
|
dea2795499 | ||
|
|
650e4fb3a9 | ||
|
|
29a630dcd1 | ||
|
|
7733ea0c02 | ||
|
|
3d13d65c52 | ||
|
|
575058550a | ||
|
|
ad3e3cb7ec | ||
|
|
e24ca7ca4a | ||
|
|
1b6d8c8f6d | ||
|
|
27e172cbe3 | ||
|
|
e40c720f99 | ||
|
|
c8d7071741 | ||
|
|
5c2154253d | ||
|
|
3c79cca77c | ||
|
|
65c0ab724f | ||
|
|
d5d259e13e | ||
|
|
691d3929eb | ||
|
|
57b3b7b5d7 | ||
|
|
1582c1a3cf | ||
|
|
e22fe940c1 | ||
|
|
7f19892444 | ||
|
|
123a016ec0 | ||
|
|
5b6dcb3bc4 | ||
|
|
8d71200b66 | ||
|
|
6d333d2b40 | ||
|
|
baacfd4469 | ||
|
|
e8925ce697 | ||
|
|
e40c2a6736 | ||
|
|
b9518dc92b | ||
|
|
47f26f2336 | ||
|
|
fbc8d98209 | ||
|
|
27aeda8921 | ||
|
|
4c2e642a85 | ||
|
|
f8995827f6 | ||
|
|
d7593d12f2 | ||
|
|
cd471a8323 | ||
|
|
9ad962c7d0 | ||
|
|
b4e16ca445 | ||
|
|
c2269fe23d | ||
|
|
d720435945 | ||
|
|
e33b0d39f9 | ||
|
|
bbf3fb96be | ||
|
|
09567234cd | ||
|
|
1c2179fc50 | ||
|
|
c7fff5d9e4 | ||
|
|
25badd6c2e | ||
|
|
97fb7b9427 | ||
|
|
f9b1aba27d | ||
|
|
aa0b9acabc | ||
|
|
67b3ae5170 | ||
|
|
7d796ebdb3 | ||
|
|
5737e68b8f | ||
|
|
211019b78b | ||
|
|
1db6676c45 | ||
|
|
da7ae028bf | ||
|
|
f3aa739e72 | ||
|
|
7f09d1a1d1 | ||
|
|
5a8483e78d | ||
|
|
841d15056d | ||
|
|
09cdd0fff0 | ||
|
|
ebb677d203 | ||
|
|
cf3236f57f | ||
|
|
3bd8169600 | ||
|
|
f9aaec6020 | ||
|
|
bb2cc995d6 | ||
|
|
a65aaa5f95 | ||
|
|
92b9a978dc | ||
|
|
5f2729e065 | ||
|
|
37bb4cea43 | ||
|
|
79d608feea | ||
|
|
54573de3e3 | ||
|
|
a2243b8825 | ||
|
|
2fba2d3b4a | ||
|
|
fd0cbbdcb1 | ||
|
|
b6e3deedf4 | ||
|
|
4c74bf1b4a | ||
|
|
2a4e3c8c58 | ||
|
|
e34e5b4260 | ||
|
|
ae2df7dfe4 | ||
|
|
1b3d0a5cf2 | ||
|
|
4c94329071 | ||
|
|
6ffcf2f865 | ||
|
|
e2c9a66880 | ||
|
|
e9bc25ebc7 | ||
|
|
6379e63669 | ||
|
|
70a0763e7f | ||
|
|
863080e6ce | ||
|
|
3ef454b8bd | ||
|
|
2bbdfc71d0 | ||
|
|
d1c783dde1 | ||
|
|
644da67601 | ||
|
|
b8d99efd29 | ||
|
|
4067d92a44 | ||
|
|
13a17f3a6b | ||
|
|
57c679e500 | ||
|
|
f70f45dab6 | ||
|
|
8d8f723d66 | ||
|
|
7c3c6a7ad7 | ||
|
|
d7a1c9377a | ||
|
|
2a317372b2 | ||
|
|
402f7bd267 | ||
|
|
e8eb6e3068 | ||
|
|
3dd9c45777 | ||
|
|
7255229361 | ||
|
|
4d2fa29886 | ||
|
|
ef90faf98b | ||
|
|
82caa8365e | ||
|
|
391257e9e9 | ||
|
|
b082253167 | ||
|
|
8df701e3fe | ||
|
|
9f232f5dbf | ||
|
|
7017726dcb | ||
|
|
b48ca8fd1e | ||
|
|
88d5e15a5e | ||
|
|
e9537cbd1d | ||
|
|
8e216bf3ac | ||
|
|
63352cc615 | ||
|
|
e9e2563739 | ||
|
|
87bb098445 | ||
|
|
da1944bedf | ||
|
|
d4a92e0d46 | ||
|
|
0fa6c1f235 | ||
|
|
260b1ba5ca | ||
|
|
f0799a6a0e | ||
|
|
155238946a | ||
|
|
45f91cf40c | ||
|
|
94f5b56b6a | ||
|
|
46db467073 | ||
|
|
17dde536d9 | ||
|
|
be67bf4b84 | ||
|
|
8f142548fe | ||
|
|
a68f439f39 | ||
|
|
7a0892bb36 | ||
|
|
8457390156 | ||
|
|
72be3898c1 | ||
|
|
d35bf5af63 | ||
|
|
04d3af6484 | ||
|
|
26920e4a98 | ||
|
|
7419966b51 | ||
|
|
58b832c6c3 | ||
|
|
99f2ec1879 | ||
|
|
4249f9ef86 | ||
|
|
60107ae299 | ||
|
|
6a95a865fa | ||
|
|
9e32589af5 | ||
|
|
6133e225e1 | ||
|
|
348c143d92 | ||
|
|
ce00785ffe | ||
|
|
78cdce750d | ||
|
|
f3f95ae282 | ||
|
|
018885eb30 | ||
|
|
c6c8a76dd6 | ||
|
|
3cae8b7230 | ||
|
|
814c8de0c2 | ||
|
|
32fe175b48 | ||
|
|
b901f6de8d | ||
|
|
fe9ba3246c | ||
|
|
71a39f0fc1 | ||
|
|
f7556898e1 | ||
|
|
578539f5d0 | ||
|
|
7c28c7fbea | ||
|
|
88bcadff81 | ||
|
|
25e25dfbf0 | ||
|
|
ba3dc0178d | ||
|
|
91e7f424bb | ||
|
|
b89f791eb0 | ||
|
|
ad3a0425ab | ||
|
|
7cf52ecf3e | ||
|
|
b1ef18f4fd | ||
|
|
b74af5bbe9 | ||
|
|
b8aa4bbfc4 | ||
|
|
e024ac9272 | ||
|
|
c5fa027a8e | ||
|
|
b6ec2b25be | ||
|
|
a756b59c60 | ||
|
|
8687ce55ed | ||
|
|
1ac6985dd0 | ||
|
|
986b4a878f | ||
|
|
1ef38fe7f3 | ||
|
|
bcad0af35e | ||
|
|
b5b89fde4f | ||
|
|
be1fc710ed | ||
|
|
aa55fd3070 | ||
|
|
a132462466 | ||
|
|
df393ff607 | ||
|
|
64040f0407 | ||
|
|
0c1abdd507 | ||
|
|
53594e3343 | ||
|
|
c6c06b87c5 | ||
|
|
ae6eb5d72d | ||
|
|
bbce53fdf4 | ||
|
|
fdd7e60c1d | ||
|
|
3b9a489d5c | ||
|
|
de40ccb759 | ||
|
|
a04d584402 | ||
|
|
a14a6a798b | ||
|
|
636d329dba | ||
|
|
d1e97dac57 | ||
|
|
41fbca8f65 | ||
|
|
535b48e5b4 | ||
|
|
d3e8d35e5d | ||
|
|
da8073141e | ||
|
|
030665732a | ||
|
|
cc042dd77c | ||
|
|
773624769d | ||
|
|
0b1d0c74fe | ||
|
|
760d307478 | ||
|
|
084c2abfc2 | ||
|
|
df6b08024f | ||
|
|
25498695ef | ||
|
|
5c81179d60 | ||
|
|
58d150bb03 | ||
|
|
2b1951ea5f | ||
|
|
5a5089c413 | ||
|
|
dcd20e4b73 | ||
|
|
88a6f436ef | ||
|
|
ee8f44d816 | ||
|
|
0308ec355f | ||
|
|
3ac14f8a2a | ||
|
|
2b087b76dc | ||
|
|
1715e5ddfa | ||
|
|
6cc17161a5 | ||
|
|
5d1c20617b | ||
|
|
d9efa48c9c | ||
|
|
dedd4cb7f0 | ||
|
|
42b147b656 | ||
|
|
47ce490d6c | ||
|
|
5563a1cadd | ||
|
|
7beb2e5ef6 | ||
|
|
f00da13cba | ||
|
|
bfed1747f7 | ||
|
|
abb4b104fa | ||
|
|
b69b1caa72 |
@@ -9,7 +9,7 @@ insert_final_newline = true
|
||||
max_line_length = 120
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[{*.har,*.json}]
|
||||
[{*.har,*.json,*yml}]
|
||||
indent_size = 2
|
||||
|
||||
[*.kt]
|
||||
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Ask a question
|
||||
url: https://github.com/florisboard/florisboard/discussions/new?category=q-a
|
||||
about: Ask here if you have a question about FlorisBoard or need assistance
|
||||
- name: General feedback
|
||||
url: https://github.com/florisboard/florisboard/blob/master/CONTRIBUTING.md
|
||||
url: https://github.com/florisboard/florisboard/discussions/new?category=feedback
|
||||
about: Give general feedback about this project
|
||||
|
||||
15
.github/ISSUE_TEMPLATE/feature_request.md
vendored
15
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -8,12 +8,11 @@ assignees: ''
|
||||
---
|
||||
|
||||
<!--
|
||||
- Describe your idea in a short but concise way.
|
||||
- If you have multiple ideas which are not directly connected to each
|
||||
other, file an issue per idea. This makes it easy to implement one
|
||||
feature proposal at a time.
|
||||
- If you have any examples, e.g. screenshots or other keyboards which
|
||||
have the proposed feature implemented, link them here.
|
||||
- Please search existing proposals to avoid creating duplicates.
|
||||
- Thank you for your help in making FlorisBoard better!
|
||||
Thank you for your help in making FlorisBoard better!
|
||||
|
||||
Guide to a good feature-request:
|
||||
• Please search existing proposals to avoid creating duplicates.
|
||||
• If you have multiple ideas which are not directly connected to other, file a new issue for each idea. This makes it easier to implement your proposals.
|
||||
• Describe your idea in a short but concise way.
|
||||
• If you have any examples, e.g. screenshots or other keyboards have the proposed feature implemented, feel free to post them after your description.
|
||||
-->
|
||||
|
||||
16
.github/ISSUE_TEMPLATE/question.md
vendored
16
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -1,16 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask here if you have a question about FlorisBoard
|
||||
title: ''
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
- If you need assistance in using FlorisBoard, ask it here!
|
||||
- If you want to suggest an idea for this project, please use the
|
||||
Feature request template instead.
|
||||
- Please search existing questions to avoid creating duplicates.
|
||||
- Thank you for your help in making FlorisBoard better!
|
||||
-->
|
||||
12
.github/workflows/android.yml
vendored
12
.github/workflows/android.yml
vendored
@@ -11,11 +11,15 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: set up JDK 1.8
|
||||
- uses: actions/checkout@v2
|
||||
- name: Checkout submodules
|
||||
run: git submodule update --init --recursive
|
||||
- name: set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
java-version: 11
|
||||
- name: Setup CMake and Ninja
|
||||
uses: lukka/get-cmake@v3.20.1
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
@@ -25,7 +29,7 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew clean assemble
|
||||
run: ./gradlew clean assembleDebug
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: app-debug.apk
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -39,4 +39,10 @@ captures/
|
||||
|
||||
# Keystore files
|
||||
*.jks
|
||||
crowdin.properties
|
||||
crowdin.properties
|
||||
|
||||
# C++
|
||||
.cxx/
|
||||
|
||||
# AndroidX Room schema JSONs
|
||||
/app/schemas/
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "app/src/main/icu4c"]
|
||||
path = app/src/main/icu4c
|
||||
url = https://github.com/florisboard/icu4c
|
||||
@@ -7,8 +7,13 @@ provides some general guidelines for each type of contribution.
|
||||
|
||||
## Giving general feedback
|
||||
|
||||
Either use the review function within Google Play or email me at
|
||||
[florisboard@patrickgold.dev](mailto:florisboard@patrickgold.dev). I
|
||||
NEW! You can now [give general feedback](https://github.com/florisboard/florisboard/discussions/new?category=feedback)
|
||||
directly here on GitHub. This is the preferred way to give feedback, as
|
||||
it allows not only for me to read and respond to feedback, but for everyone
|
||||
in this community.
|
||||
|
||||
Optionally you can also use the review function within Google Play or email me
|
||||
at [florisboard@patrickgold.dev](mailto:florisboard@patrickgold.dev). I
|
||||
love to hear from you! Note, that the amount of feedback emails I get
|
||||
is overwhelmingly high - so if I don't answer or answer really late, I
|
||||
apologize - I guarantee though that I read through every email and that
|
||||
@@ -41,7 +46,7 @@ syntax (it is very easy though by just looking at some other layout files).
|
||||
There are two main steps in adding new layouts, though the config step can
|
||||
be skipped if you only add a layout without a new default language support.
|
||||
|
||||
### The config file (`app/src/main/assets/ime/config.json`)
|
||||
### The config file ([`app/src/main/assets/ime/config.json`](app/src/main/assets/ime/config.json))
|
||||
|
||||
This file is very important, as it defines all default currency sets as
|
||||
well as all default subtypes available in the Settings Subtype UI. Note
|
||||
@@ -66,7 +71,7 @@ pre-configured language.
|
||||
|
||||
Since v0.3.10-beta05 it is possible to add custom layouts for all types.
|
||||
|
||||
To add a new layout, head to `app/src/main/assets/ime/text` and then select
|
||||
To add a new layout, head to [`app/src/main/assets/ime/text`](app/src/main/assets/ime/text) and then select
|
||||
the correct sub-directory for the type of layout you want to add. In most cases
|
||||
this will be `characters` to add a layout like QWERTY etc.
|
||||
|
||||
@@ -74,14 +79,14 @@ For the `code` field of each key, make sure to use the UTF-8 code. An
|
||||
useful tool for finding the correct code is [unicode-table.com](https://unicode-table.com/en/).
|
||||
From there, you search for your letter and then use the HTML code, but without the `&#;`
|
||||
For internal codes of functional or UI keys, see
|
||||
`app/src/main/java/dev/patrickgold/florisboard/ime/text/key/KeyCode.kt`.
|
||||
[`app/src/main/java/dev/patrickgold/florisboard/ime/text/key/KeyCode.kt`](app/src/main/java/dev/patrickgold/florisboard/ime/text/key/KeyCode.kt).
|
||||
|
||||
The label is equally important and should always match up with the defined
|
||||
code. If `code` and `label` don't match up, FlorisBoard won't crash but
|
||||
it will most likely lead to confusion in the key processing logic.
|
||||
|
||||
Any accents or diacritics that should be exposed via long press can be
|
||||
added at `assets/ime/text/characters/extended_popups/<languageTag_name_here>.json`.
|
||||
added at [`app/src/main/assets/ime/text/characters/extended_popups/<languageTag_name_here>.json`](app/src/main/assets/ime/text/characters/extended_popups).
|
||||
For each key, you can add 1 main and several relevant accents. The main
|
||||
accent should be used for accents which are important for the language
|
||||
you add. The main field is used for determining if a hint or an accent
|
||||
|
||||
220
README.md
220
README.md
@@ -7,171 +7,68 @@ src="fastlane/metadata/android/en-US/images/icon.png" alt="App icon">
|
||||
devices. It aims at being modern, user-friendly and customizable while
|
||||
fully respecting your privacy. Currently in early-beta state.
|
||||
|
||||
### Stable [](https://github.com/florisboard/florisboard/releases/latest)
|
||||
<table>
|
||||
<tr>
|
||||
<th align="center" width="50%">
|
||||
<h3>Stable <a href="https://github.com/florisboard/florisboard/releases"><img alt="Latest stable release" src="https://img.shields.io/github/v/release/florisboard/florisboard"></a></h3>
|
||||
</th>
|
||||
<th align="center" width="50%">
|
||||
<h3>Beta <a href="https://github.com/florisboard/florisboard/releases/latest"><img alt="Latest beta release" src="https://img.shields.io/github/v/release/florisboard/florisboard?include_prereleases"></a></h3>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">
|
||||
<p><i>Major versions only, 1 release per 1-3 months</i><br><br>Updates are more polished, new features are matured and tested through to ensure a stable experience.</p>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<p><i>Beta versions, 1-2 releases per week</i><br><br>Updates contain new features that may not be fully matured yet and bugs are more likely to occur. Allows you to give early feedback.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">
|
||||
<p><a href="https://f-droid.org/packages/dev.patrickgold.florisboard"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" height="64" alt="F-Droid badge"></a></p>
|
||||
<p>
|
||||
|
||||
Releases on this track are in general stable and ready for everyday use, except for features marked as experimental. Use one of the following options to receive FlorisBoard's stable releases:
|
||||
**Google Play**: Join the [FlorisBoard Test Group](https://groups.google.com/g/florisboard-public-alpha-test), then visit the [testing page](https://play.google.com/apps/testing/dev.patrickgold.florisboard). Once joined and installed, updates will be delivered like for any other app. ([Store entry](https://play.google.com/store/apps/details?id=dev.patrickgold.florisboard))
|
||||
|
||||
_A. Get it on F-Droid_:
|
||||
</p>
|
||||
<p>
|
||||
|
||||
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" height="64" alt="F-Droid badge">](https://f-droid.org/packages/dev.patrickgold.florisboard)
|
||||
**Manual**: Download and install the APK from the release page.
|
||||
|
||||
_B. Google Play Public Alpha Test_:
|
||||
</p>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<p><a href="https://apt.izzysoft.de/fdroid/index/apk/dev.patrickgold.florisboard.beta"><img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png" height="64" alt="IzzySoft repo badge"></a></p>
|
||||
<p>
|
||||
|
||||
You can join the public alpha test programme on Google Play. To become a
|
||||
tester, follow these steps:
|
||||
1. Join the
|
||||
[FlorisBoard Public Alpha Test](https://groups.google.com/g/florisboard-public-alpha-test)
|
||||
Google Group to be able to access the testing programme.
|
||||
2. Go to the
|
||||
[FlorisBoard Testing Page](https://play.google.com/apps/testing/dev.patrickgold.florisboard),
|
||||
then click "Become a tester". Now you are enrolled in the testing
|
||||
programme.
|
||||
3. To try out FlorisBoard, download it via Google Play. To do so, click
|
||||
on "Download it on Google Play", which takes you to the [PlayStore
|
||||
listing](https://play.google.com/store/apps/details?id=dev.patrickgold.florisboard).
|
||||
4. Finished! You will receive future versions of FlorisBoard via Google
|
||||
Play.
|
||||
**Google Play**: Join the [FlorisBoard Test Group](https://groups.google.com/g/florisboard-public-alpha-test), then visit the [beta testing page](https://play.google.com/apps/testing/dev.patrickgold.florisboard.beta). Once joined and installed, updates will be delivered like for any other app. ([Store entry](https://play.google.com/store/apps/details?id=dev.patrickgold.florisboard.beta))
|
||||
|
||||
With the v0.4.0 release FlorisBoard will enter the public beta in GPlay, allowing to directly search
|
||||
for and download FlorisBoard without prior joining the alpha group.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
_C. Use the APK provided in the release section of this repo_
|
||||
**Manual**: Download and install the APK from the release page.
|
||||
|
||||
### Beta [](https://github.com/florisboard/florisboard/releases)
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Releases on this track are also in general stable and should be ready for everyday use, though crashes and bugs are more likely to occur. Use releases from this track if you want to get new features faster and give feedback for brand-new stuff. Options to get beta releases:
|
||||
Beginning with v0.4.0 FlorisBoard will follow [SemVer](https://semver.org/#summary) versioning scheme and enter the public beta on Google Play.
|
||||
|
||||
_A. IzzySoft's repo for F-Droid_:
|
||||
|
||||
[<img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png" height="64" alt="IzzySoft repo badge">](https://apt.izzysoft.de/fdroid/index/apk/dev.patrickgold.florisboard.beta)
|
||||
|
||||
_B. Use the APK provided in the release section of this repo_
|
||||
|
||||
### Giving feedback
|
||||
If you want to give feedback to FlorisBoard, there are several ways to
|
||||
do so, as listed [here](CONTRIBUTING.md#giving-general-feedback).
|
||||
|
||||
---
|
||||
|
||||
<img align="right" height="256"
|
||||
src="https://patrickgold.dev/media/previews/florisboard-preview-day.png"
|
||||
alt="Preview image">
|
||||
|
||||
## Implemented features
|
||||
This list contains all implemented and fully functional features
|
||||
FlorisBoard currently has to offer. For planned features and its
|
||||
milestones, please refer to the [Feature roadmap](#feature-roadmap).
|
||||
|
||||
### Basics
|
||||
* [x] Implementation of the keyboard core (InputMethodService)
|
||||
* [x] Custom implementation of deprecated KeyboardView (base only)
|
||||
* [x] Caps + Caps Lock
|
||||
* [x] Key popups
|
||||
* [x] Extended key popups (e.g. a -> á, à, ä, ...)
|
||||
* [x] Key press sound/vibration
|
||||
* [x] Portrait orientation support
|
||||
* [x] Landscape orientation support (needs tweaks)
|
||||
|
||||
### Layouts
|
||||
* [x] Latin character layouts (QWERTY, QWERTZ, AZERTY, Swiss, Spanish, Norwegian, Swedish/Finnish, Icelandic, Danish,
|
||||
Hungarian, Croatian, Polish, Romanian, Colemak, Dvorak, Turkish-Q, Turkish-F, ...)
|
||||
* [x] Non-latin character layouts (Arabic, Persian, Kurdish, Greek, Russian (JCUKEN))
|
||||
* [x] Adapt to situation in app (password, url, text, etc. )
|
||||
* [x] Special character layout(s)
|
||||
* [x] Numeric layout
|
||||
* [x] Numeric layout (advanced)
|
||||
* [x] Phone number layout
|
||||
* [x] Emoji layout
|
||||
* [x] Emoticon layout
|
||||
|
||||
### Preferences
|
||||
* [x] Setup wizard
|
||||
* [x] Preferences screen
|
||||
* [x] Customize look and behaviour of keyboard
|
||||
* [x] Theme presets (currently only day/night theme + borderless)
|
||||
* [x] Theme customization
|
||||
* [x] Subtype selection (language/layout)
|
||||
* [x] Keyboard behaviour preferences
|
||||
* [x] Gesture preferences
|
||||
|
||||
### Other useful features
|
||||
* [x] One-handed mode
|
||||
* [x] Clipboard/cursor tools
|
||||
* [x] Clipboard manager/history
|
||||
* [x] Integrated number row / symbols in character layouts
|
||||
* [x] Gesture support
|
||||
* [x] Full integration in IME service list of Android (xml/method)
|
||||
(integration is internal-only, because Android's default subtype
|
||||
implementation not really allows for dynamic language/layout
|
||||
pairs, only compile-time defined ones)
|
||||
* [ ] Description and settings reference in System Language & Input
|
||||
* [ ] (dev only) Generate well-structured documentation of code
|
||||
* [ ] ...
|
||||
|
||||
## Feature roadmap
|
||||
This section describes the features which are planned to be implemented
|
||||
in FlorisBoard for the next major versions, modularized into sections.
|
||||
Please note that the milestone due dates are only raw estimates and will
|
||||
most likely be delayed back, even though I'm eager to stick to these as
|
||||
close as possible.
|
||||
|
||||
### [v0.4.0](https://github.com/florisboard/florisboard/milestone/4)
|
||||
- Module A: Smartbar rework (Implemented with [#91])
|
||||
- Ability to enable/disable Smartbar (features below thus only work if
|
||||
Smartbar is enabled)
|
||||
- Dynamic switching between clipboard tools and word suggestions
|
||||
- Ability to show both the number row and word suggestions at once
|
||||
- Better icons in quick actions
|
||||
- Complete rework of the Smartbar code base and the Smartbar layout
|
||||
definition in XML
|
||||
|
||||
- Module B: Composing suggestions (Phase 1: [#329])
|
||||
- Auto-suggestion of words based of precompiled dictionaries
|
||||
- Management of custom dictionary entries
|
||||
- Next-word suggestions by training language models. Data collected here is stored locally and never leaves
|
||||
the user's device.
|
||||
|
||||
- Module C: Extension packs (base implementation with [#162])
|
||||
- Ability to load dictionaries (and later potentially other cool
|
||||
features too) only if needed to keep the core APK size small
|
||||
- Currently unclear how exactly this will work, but this is definitely
|
||||
a must-have feature
|
||||
|
||||
- Module D: Glide typing
|
||||
- Swiping over the characters will automatically convert this to a word
|
||||
- Possibly also add improvements based on the Flow keyboard
|
||||
|
||||
- Module E: Theme rework (Implemented with [#162])
|
||||
- Themes are now based on the Asset schema
|
||||
- Dynamic theme creation
|
||||
- Different theme modes (`Always day`, `Always night`, `Follow system`
|
||||
and `Follow time`)
|
||||
- Define a separate theme both for day and night theme
|
||||
- Adapt to app theme if possible
|
||||
- Theme import/export
|
||||
|
||||
### [v0.5.0](https://github.com/florisboard/florisboard/milestone/5)
|
||||
There's no exact roadmap yet but it is planned that the media part of
|
||||
FlorisBoard (emojis, emoticons, kaomoji) gets a rework. Also as an extension
|
||||
(requires v0.4.0/Module C) GIF support is planned.
|
||||
|
||||
### > v0.5.0
|
||||
This is completely open as of now and will gather planned features as time
|
||||
passes...
|
||||
|
||||
Backlog (currently not assigned to any milestone):
|
||||
|
||||
- Floating keyboard
|
||||
|
||||
[#91]: https://github.com/florisboard/florisboard/pull/91
|
||||
[#162]: https://github.com/florisboard/florisboard/pull/162
|
||||
[#329]: https://github.com/florisboard/florisboard/pull/329
|
||||
## Highlighted features
|
||||
- Spell checking service
|
||||
- Word suggestions (currently English only and may not work on all devices)
|
||||
- Glide typing (currently English only)
|
||||
- Advanced theming support and customization
|
||||
- Integrated clipboard manager / history
|
||||
- Emoji keyboard (although lacking some features)
|
||||
|
||||
## Contributing
|
||||
Wanna contribute to FlorisBoard? That's great to hear! There are lots of
|
||||
different ways to help out. Bug reporting, making pull requests,
|
||||
translating FlorisBoard to make it more accessible, etc. For more
|
||||
information see the . Thank
|
||||
information see the [contributing guidelines](CONTRIBUTING.md). Thank
|
||||
you for your help!
|
||||
|
||||
## List of permissions FlorisBoard requests
|
||||
@@ -183,29 +80,18 @@ to get more information on this topic.
|
||||
by [google](https://github.com/google)
|
||||
* [Google Material icons](https://github.com/google/material-design-icons) by
|
||||
[google](https://github.com/google)
|
||||
* [Moshi JSON library](https://github.com/square/moshi) by
|
||||
[square](https://github.com/square)
|
||||
* [KotlinX serialization library](https://github.com/Kotlin/kotlinx.serialization) by
|
||||
[Kotlin](https://github.com/Kotlin)
|
||||
* [ColorPicker preference](https://github.com/jaredrummler/ColorPicker) by
|
||||
[Jared Rummler](https://github.com/jaredrummler)
|
||||
* [Timber](https://github.com/JakeWharton/timber) by
|
||||
[JakeWharton](https://github.com/JakeWharton)
|
||||
* [expandable-fab](https://github.com/nambicompany/expandable-fab) by
|
||||
[Nambi](https://github.com/nambicompany)
|
||||
|
||||
## Usage notes for included binary dictionary files
|
||||
All binary dictionaries included within this project in
|
||||
(this)[app/src/main/assets/ime/dict) asset folder are built from various
|
||||
sources, as stated below.
|
||||
|
||||
### Source 1: [wordfreq library by LuminosoInsight](https://github.com/LuminosoInsight/wordfreq):
|
||||
`wordfreq` is a repository which provides both a Python library and raw
|
||||
data (the wordlists). Only the data has been extracted in order to build
|
||||
binary dictionary files from it. `wordfreq`'s data is licensed under the
|
||||
Creative Commons Attribution-ShareAlike 4.0 license
|
||||
(https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
|
||||
For further information on what wordfreq's data depends on, see
|
||||
(https://github.com/LuminosoInsight/wordfreq#license).
|
||||
* [ICU4C](https://github.com/unicode-org/icu) by
|
||||
[The Unicode Consortium](https://github.com/unicode-org)
|
||||
* [Nuspell](https://github.com/nuspell/nuspell) by
|
||||
[Nuspell](https://github.com/nuspell)
|
||||
|
||||
## License
|
||||
```
|
||||
|
||||
106
ROADMAP.md
Normal file
106
ROADMAP.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# FlorisBoard's feature roadmap & milestones
|
||||
|
||||
This feature roadmap intents to provide transparency to what I want to add
|
||||
to FlorisBoard in the foreseeable future. Note that there are no ETAs for any
|
||||
version milestones down below, experience says these won't hold anyways.
|
||||
|
||||
I try my best to release regularly, though some features take a lot longer
|
||||
than others and thus releases can be spaced out a bit on the stable track.
|
||||
If you are interested in following the development more closely, make sure to
|
||||
follow along the beta track releases! These are generally more unstable but
|
||||
you get new stuff faster and can provide early feedback, which helps a lot!
|
||||
|
||||
## 0.3.x and 0.4.0
|
||||
Releases in this section still follow the old versioning scheme, meaning the
|
||||
patch number is a feature upgrade. As this naming convention is more confusing
|
||||
than useful, after the v0.4.0 release a new release/development cycle will be
|
||||
introduced.
|
||||
|
||||
### 0.3.13 (currently in development and soon done)
|
||||
- Spell checking (mainly completed and relatively well working, Smartbar integration still missing)
|
||||
- Performance improvements in keyboard rendering
|
||||
- Audio/haptic feedback rework
|
||||
- Lots and lots of bug fixing in all areas, really fix some annoying bugs
|
||||
- New layouts added by contributors
|
||||
|
||||
### 0.3.14
|
||||
- Re-write of the Preference core
|
||||
- Reduce redundancy in key/default value definitions
|
||||
- Avoid having to manually add redundant code for adding a new pref
|
||||
- Goes hand-in-hand with the Settings UI re-write
|
||||
- Re-write of the Settings UI with Jetpack Compose
|
||||
- Also re-structure UI into a more list-like panel
|
||||
- Adjust theme colors of Settings a bit to make it more modern
|
||||
- Preview the keyboard at any time from within the Settings
|
||||
- Settings language different than device language
|
||||
- Re-write the Setup UI in Jetpack Compose
|
||||
- Simplify screen based on previously discussed ideas and mock-ups
|
||||
- Improve backend setup logic
|
||||
- Implement base-UI for extensions and further continue development
|
||||
of existing Flex (FlorisBoard extension) format
|
||||
- Allows for a continuous experience of customizing FlorisBoard in different areas
|
||||
- Planned in the future (not in this version though) what will use Flex:
|
||||
- Themes
|
||||
- Layouts (Characters, symbols, numeric, ...)
|
||||
- Composers for non-Latin script languages
|
||||
- Word suggestion dictionaries
|
||||
- Spell check dictionaries
|
||||
- User dictionaries
|
||||
- Other features that require only data and no logic
|
||||
- Maybe full backup of preferences? Not 100% confirmed though and may be pushed back
|
||||
|
||||
### 0.3.15
|
||||
- Re-adding word suggestions (at least for Latin-based languages at first)
|
||||
- Importing the dictionaries as well as management relies on the Flex extension core and UI in Kotlin
|
||||
- Actually parsing and generating suggestions happens in C++ to avoid another OOM catastrophe like in 0.3.9/10
|
||||
- The actual format of the dictionary and word list source is not decided yet
|
||||
- Improvement of the candidate view in Smartbar (for word suggestions)
|
||||
- Theme rework part I:
|
||||
- Custom key corner radius
|
||||
- Custom key border color (not shadow!!)
|
||||
- Re-work theme internals so they use Flex format
|
||||
- Community repository on GitHub for theme sharing across users (when Theme Flex format is ready)
|
||||
|
||||
### 0.4.0
|
||||
- Prepare FlorisBoard repository and app store presence for public beta release
|
||||
on Google Play
|
||||
- Rework branding images and texts of FlorisBoard for the app stores
|
||||
- Focus on polishing the app and fixing bugs/crashes
|
||||
|
||||
With this release the versioning scheme changes: the second number now indicates new features,
|
||||
changes in the third "patch" number now indicates bug fixes for the stable track. The development
|
||||
cycle for each 0.x release will have -betaXX and -rcXX (release candidate) releases on the beta
|
||||
track for interested people to follow along the development.
|
||||
|
||||
## 0.5.0
|
||||
- Complete rework of the Emoji panel
|
||||
- Recently used / Emoji history
|
||||
- Emoji search
|
||||
- Emoji suggestions when using :emoji_name: syntax
|
||||
- Kaomoji panel implementation (the third tab which currently has "not yet implemented")
|
||||
- Full Smartbar customization
|
||||
- Includes internal rework how Smartbar is build and assembled
|
||||
- Allow for more than one Smartbar / Stackable and Collapsible Smartbars
|
||||
- Customizable quick actions, clipboard row
|
||||
|
||||
## 0.6.0
|
||||
- Full on-board layout editor which allows users to create their own layouts
|
||||
without writing a JSON file
|
||||
- Import/Export of custom layout files packed in Flex extensions
|
||||
|
||||
## Backlog / Features that MAY be added
|
||||
- Theme rework part II
|
||||
- Adaptive themes v2
|
||||
- Voice-to-text with Mozilla's open-source voice service
|
||||
- Text translation
|
||||
- Glide typing better word detection
|
||||
- Proximity-based key typo detection
|
||||
- Floating keyboard
|
||||
- Tablet mode / Optimizations for landscape input
|
||||
- Stickers/GIFs
|
||||
- FlorisBoard landing web page for presentation
|
||||
- Implementing additional layouts
|
||||
- Support for Tasker/Automate/MacroDroid plugins
|
||||
- Support for WearOS/Smartwatches
|
||||
- Handwriting
|
||||
- ...
|
||||
@@ -1,14 +1,14 @@
|
||||
|
||||
plugins {
|
||||
id("com.android.application") version "4.1.3"
|
||||
kotlin("android") version "1.5.0-RC"
|
||||
kotlin("kapt") version "1.5.0-RC"
|
||||
kotlin("plugin.serialization") version "1.5.0-RC"
|
||||
id("com.android.application") version "7.0.2"
|
||||
kotlin("android") version "1.5.21"
|
||||
kotlin("kapt") version "1.5.21"
|
||||
kotlin("plugin.serialization") version "1.5.21"
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion(30)
|
||||
buildToolsVersion("30.0.3")
|
||||
compileSdk = 31
|
||||
buildToolsVersion = "30.0.3"
|
||||
ndkVersion = "22.1.7171670"
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
@@ -17,21 +17,66 @@ android {
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
freeCompilerArgs = listOf("-Xallow-result-return-type", "-Xopt-in=kotlin.RequiresOptIn")
|
||||
freeCompilerArgs = listOf("-Xallow-result-return-type", "-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.contracts.ExperimentalContracts")
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "dev.patrickgold.florisboard"
|
||||
minSdkVersion(23)
|
||||
targetSdkVersion(30)
|
||||
versionCode(39)
|
||||
versionName("0.3.11")
|
||||
minSdk = 23
|
||||
targetSdk = 30
|
||||
versionCode = 57
|
||||
versionName = "0.3.14"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
arguments += mapOf(
|
||||
Pair("room.schemaLocation", "$projectDir/schemas"),
|
||||
Pair("room.incremental", "true"),
|
||||
Pair("room.expandProjection", "true")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
cFlags("-fvisibility=hidden", "-DU_STATIC_IMPLEMENTATION=1")
|
||||
cppFlags("-fvisibility=hidden", "-std=c++17", "-fexceptions", "-ffunction-sections", "-fdata-sections", "-DU_DISABLE_RENAMING=1", "-DU_STATIC_IMPLEMENTATION=1")
|
||||
arguments("-DANDROID_STL=c++_static")
|
||||
}
|
||||
}
|
||||
|
||||
ndk {
|
||||
//abiFilters += listOf("x86", "x86_64", "armeabi-v7a", "arm64-v8a")
|
||||
abiFilters += listOf("armeabi-v7a", "arm64-v8a")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
maybeCreate("main").apply {
|
||||
assets {
|
||||
srcDirs("src/main/assets", "src/main/icu4c/prebuilt/assets")
|
||||
}
|
||||
jniLibs {
|
||||
srcDirs("src/main/icu4c/prebuilt/jniLibs")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
compose = true
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = "1.0.1"
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path("src/main/cpp/CMakeLists.txt")
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@@ -39,6 +84,9 @@ android {
|
||||
applicationIdSuffix = ".debug"
|
||||
versionNameSuffix = "-debug"
|
||||
|
||||
isDebuggable = true
|
||||
isJniDebuggable = true
|
||||
|
||||
resValue("mipmap", "floris_app_icon", "@mipmap/ic_app_icon_debug")
|
||||
resValue("mipmap", "floris_app_icon_round", "@mipmap/ic_app_icon_debug_round")
|
||||
resValue("string", "floris_app_name", "FlorisBoard Debug")
|
||||
@@ -47,7 +95,7 @@ android {
|
||||
create("beta") // Needed because by default the "beta" BuildType does not exist
|
||||
named("beta").configure {
|
||||
applicationIdSuffix = ".beta"
|
||||
versionNameSuffix = "-beta04"
|
||||
versionNameSuffix = "-beta01"
|
||||
proguardFiles.add(getDefaultProguardFile("proguard-android-optimize.txt"))
|
||||
|
||||
resValue("mipmap", "floris_app_icon", "@mipmap/ic_app_icon_beta")
|
||||
@@ -70,33 +118,43 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
lint {
|
||||
isAbortOnError = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
implementation("androidx.activity", "activity-ktx", "1.2.1")
|
||||
implementation("androidx.appcompat", "appcompat", "1.2.0")
|
||||
implementation("androidx.core", "core-ktx", "1.3.2")
|
||||
implementation("androidx.fragment", "fragment-ktx", "1.3.0")
|
||||
implementation("androidx.preference", "preference-ktx", "1.1.1")
|
||||
implementation("androidx.constraintlayout", "constraintlayout", "2.0.4")
|
||||
implementation("androidx.lifecycle", "lifecycle-service", "2.2.0")
|
||||
implementation("com.google.android", "flexbox", "2.0.1") // requires jcenter as of version 2.0.1
|
||||
implementation("com.google.android.material", "material", "1.3.0")
|
||||
implementation("org.jetbrains.kotlinx", "kotlinx-coroutines-android", "1.4.2")
|
||||
implementation("org.jetbrains.kotlinx", "kotlinx-serialization-json", "1.1.0")
|
||||
implementation("com.jaredrummler", "colorpicker", "1.1.0")
|
||||
implementation("com.jakewharton.timber", "timber", "4.7.1")
|
||||
implementation("com.nambimobile.widgets", "expandable-fab", "1.0.2")
|
||||
implementation("androidx.room", "room-runtime", "2.2.6")
|
||||
kapt("androidx.room", "room-compiler","2.2.6")
|
||||
implementation("androidx.activity:activity-compose:1.3.1")
|
||||
implementation("androidx.activity:activity-ktx:1.3.1")
|
||||
implementation("androidx.appcompat:appcompat:1.3.1")
|
||||
implementation("androidx.autofill:autofill:1.1.0")
|
||||
implementation("androidx.compose.material:material:1.0.2")
|
||||
implementation("androidx.compose.ui:ui:1.0.2")
|
||||
implementation("androidx.compose.ui:ui-tooling-preview:1.0.2")
|
||||
implementation("androidx.constraintlayout:constraintlayout:2.1.0") // possibly remove after settings rework
|
||||
implementation("androidx.core:core-ktx:1.6.0")
|
||||
implementation("androidx.fragment:fragment-ktx:1.3.6") // possibly remove after settings rework
|
||||
implementation("androidx.navigation:navigation-compose:2.4.0-alpha08")
|
||||
implementation("androidx.preference:preference-ktx:1.1.1") // possibly remove after settings rework
|
||||
implementation("androidx.lifecycle:lifecycle-service:2.3.1")
|
||||
implementation("com.google.accompanist:accompanist-systemuicontroller:0.18.0")
|
||||
implementation("com.google.android.flexbox:flexbox:3.0.0")
|
||||
implementation("com.google.android.material:material:1.4.0")
|
||||
implementation("com.jakewharton.timber:timber:4.7.1") // possibly remove after settings rework
|
||||
implementation("com.jaredrummler:colorpicker:1.1.0") // possibly remove after settings rework
|
||||
implementation("com.nambimobile.widgets:expandable-fab:1.0.2") // possibly remove after settings rework
|
||||
implementation("dev.patrickgold.jetpref:jetpref-datastore-model:0.1.0-alpha03")
|
||||
implementation("dev.patrickgold.jetpref:jetpref-ui-compose:0.1.0-alpha03")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0")
|
||||
implementation("androidx.room:room-runtime:2.3.0")
|
||||
kapt("androidx.room:room-compiler:2.3.0")
|
||||
|
||||
testImplementation("junit", "junit", "4.13.1")
|
||||
testImplementation(kotlin("test"))
|
||||
testImplementation("androidx.test", "core", "1.3.0")
|
||||
testImplementation("org.mockito", "mockito-inline", "3.7.7")
|
||||
testImplementation("org.robolectric", "robolectric", "4.5.1")
|
||||
|
||||
androidTestImplementation("androidx.test.ext", "junit", "1.1.2")
|
||||
androidTestImplementation("androidx.test.espresso", "espresso-core", "3.3.0")
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
|
||||
<application
|
||||
android:name=".ime.core.FlorisApplication"
|
||||
android:name="dev.patrickgold.florisboard.FlorisApplication"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/floris_app_name"
|
||||
@@ -31,21 +31,42 @@
|
||||
|
||||
<!-- IME service -->
|
||||
<service
|
||||
android:name="dev.patrickgold.florisboard.ime.core.FlorisBoard"
|
||||
android:name="dev.patrickgold.florisboard.FlorisImeService"
|
||||
android:label="@string/floris_app_name"
|
||||
android:permission="android.permission.BIND_INPUT_METHOD">
|
||||
<meta-data
|
||||
android:name="android.view.im"
|
||||
android:resource="@xml/method"/>
|
||||
|
||||
android:permission="android.permission.BIND_INPUT_METHOD"
|
||||
android:directBootAware="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.view.InputMethod"/>
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.view.im" android:resource="@xml/method"/>
|
||||
</service>
|
||||
|
||||
<!-- Spellchecker service -->
|
||||
<service
|
||||
android:name="dev.patrickgold.florisboard.FlorisSpellCheckerService"
|
||||
android:label="@string/floris_app_name"
|
||||
android:permission="android.permission.BIND_TEXT_SERVICE"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.textservice.SpellCheckerService"/>
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.view.textservice.scs" android:resource="@xml/spellchecker"/>
|
||||
</service>
|
||||
|
||||
<!-- Main App Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.app.FlorisAppActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/settings__title"
|
||||
android:launchMode="singleTask"
|
||||
android:roundIcon="@mipmap/floris_app_icon_round"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:theme="@style/FlorisAppTheme"/>
|
||||
|
||||
<!-- Settings Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.settings.SettingsMainActivity"
|
||||
android:name="dev.patrickgold.florisboard.oldsettings.SettingsMainActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/settings__title"
|
||||
android:launchMode="singleTask"
|
||||
@@ -59,30 +80,46 @@
|
||||
android:label="@string/floris_app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:roundIcon="@mipmap/floris_app_icon_round"
|
||||
android:targetActivity="dev.patrickgold.florisboard.setup.SetupActivity">
|
||||
android:targetActivity="dev.patrickgold.florisboard.app.FlorisAppActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<!-- User Dictionary Manager Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.oldsettings.UdmActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/settings__title"
|
||||
android:theme="@style/SettingsTheme"/>
|
||||
|
||||
<!-- Theme Selector Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.settings.ThemeManagerActivity"
|
||||
android:name="dev.patrickgold.florisboard.oldsettings.ThemeManagerActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/settings__title"
|
||||
android:theme="@style/SettingsTheme"/>
|
||||
|
||||
<!-- Theme Editor Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.settings.ThemeEditorActivity"
|
||||
android:name="dev.patrickgold.florisboard.oldsettings.ThemeEditorActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/settings__theme_editor__title"
|
||||
android:theme="@style/SettingsTheme"/>
|
||||
|
||||
<!-- Spelling Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.oldsettings.spelling.SpellingActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/settings__spelling__title_overview"
|
||||
android:roundIcon="@mipmap/floris_app_icon_round"
|
||||
android:theme="@style/SettingsTheme"/>
|
||||
|
||||
<!-- About Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.settings.AboutActivity"
|
||||
android:name="dev.patrickgold.florisboard.oldsettings.AboutActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/about__title"
|
||||
android:roundIcon="@mipmap/floris_app_icon_round"
|
||||
@@ -90,7 +127,7 @@
|
||||
|
||||
<!-- Advanced Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.settings.AdvancedActivity"
|
||||
android:name="dev.patrickgold.florisboard.oldsettings.AdvancedActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/settings__advanced__title"
|
||||
android:roundIcon="@mipmap/floris_app_icon_round"
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"package": "dev.patrickgold.florisboard",
|
||||
"composers": [
|
||||
{ "$": "appender" },
|
||||
{ "$": "hangul-unicode" },
|
||||
{ "$": "kana-unicode" }
|
||||
],
|
||||
"currencySets": [
|
||||
{
|
||||
"name": "azerbaijani_manat",
|
||||
@@ -205,6 +210,18 @@
|
||||
{ "code": 165, "label": "¥" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "thai_baht",
|
||||
"label": "Thai baht (฿)",
|
||||
"slots": [
|
||||
{ "code": 3647, "label": "฿" },
|
||||
{ "code": 36, "label": "$" },
|
||||
{ "code": 8364, "label": "€" },
|
||||
{ "code": 162, "label": "¢" },
|
||||
{ "code": 163, "label": "£" },
|
||||
{ "code": 165, "label": "¥" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "turkish_lira",
|
||||
"label": "Turkish lira (₺)",
|
||||
@@ -246,6 +263,7 @@
|
||||
{
|
||||
"id": 101,
|
||||
"languageTag": "en-US",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -254,6 +272,7 @@
|
||||
{
|
||||
"id": 102,
|
||||
"languageTag": "en-UK",
|
||||
"composer": "appender",
|
||||
"currencySet": "pound",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -262,6 +281,7 @@
|
||||
{
|
||||
"id": 103,
|
||||
"languageTag": "en-CA",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -270,6 +290,7 @@
|
||||
{
|
||||
"id": 104,
|
||||
"languageTag": "en-AU",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -278,6 +299,7 @@
|
||||
{
|
||||
"id": 201,
|
||||
"languageTag": "de-DE",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwertz"
|
||||
@@ -286,6 +308,7 @@
|
||||
{
|
||||
"id": 202,
|
||||
"languageTag": "de-AT",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwertz"
|
||||
@@ -294,14 +317,27 @@
|
||||
{
|
||||
"id": 203,
|
||||
"languageTag": "de-CH",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "swiss_german"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 204,
|
||||
"languageTag": "de-DE-neobone",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "neo2",
|
||||
"symbols": "neo2",
|
||||
"numericRow": "neo2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 301,
|
||||
"languageTag": "fr-FR",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "azerty"
|
||||
@@ -310,6 +346,7 @@
|
||||
{
|
||||
"id": 302,
|
||||
"languageTag": "fr-CA",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "canadian_french"
|
||||
@@ -318,6 +355,7 @@
|
||||
{
|
||||
"id": 303,
|
||||
"languageTag": "fr-CH",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "swiss_french"
|
||||
@@ -326,6 +364,7 @@
|
||||
{
|
||||
"id": 401,
|
||||
"languageTag": "it-IT",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -334,6 +373,7 @@
|
||||
{
|
||||
"id": 402,
|
||||
"languageTag": "it-CH",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "swiss_italian"
|
||||
@@ -342,6 +382,7 @@
|
||||
{
|
||||
"id": 501,
|
||||
"languageTag": "es-ES",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "spanish"
|
||||
@@ -350,6 +391,7 @@
|
||||
{
|
||||
"id": 502,
|
||||
"languageTag": "es-US",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "spanish"
|
||||
@@ -358,6 +400,7 @@
|
||||
{
|
||||
"id": 503,
|
||||
"languageTag": "es-419",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "spanish"
|
||||
@@ -366,6 +409,7 @@
|
||||
{
|
||||
"id": 601,
|
||||
"languageTag": "pt-PT",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -374,6 +418,7 @@
|
||||
{
|
||||
"id": 602,
|
||||
"languageTag": "pt-BR",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -382,6 +427,7 @@
|
||||
{
|
||||
"id": 701,
|
||||
"languageTag": "nb-NO",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "norwegian"
|
||||
@@ -390,6 +436,7 @@
|
||||
{
|
||||
"id": 702,
|
||||
"languageTag": "nn-NO",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "norwegian"
|
||||
@@ -398,6 +445,7 @@
|
||||
{
|
||||
"id": 711,
|
||||
"languageTag": "sv-SE",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "swedish_finnish"
|
||||
@@ -406,6 +454,7 @@
|
||||
{
|
||||
"id": 721,
|
||||
"languageTag": "fi-FI",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "swedish_finnish"
|
||||
@@ -414,6 +463,7 @@
|
||||
{
|
||||
"id": 731,
|
||||
"languageTag": "da-DK",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "danish"
|
||||
@@ -422,6 +472,7 @@
|
||||
{
|
||||
"id": 741,
|
||||
"languageTag": "is-IS",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "icelandic"
|
||||
@@ -430,6 +481,7 @@
|
||||
{
|
||||
"id": 751,
|
||||
"languageTag": "fo",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "faroese"
|
||||
@@ -438,6 +490,7 @@
|
||||
{
|
||||
"id": 801,
|
||||
"languageTag": "fa-FA",
|
||||
"composer": "appender",
|
||||
"currencySet": "iranian_rial",
|
||||
"preferred": {
|
||||
"characters": "persian",
|
||||
@@ -449,6 +502,7 @@
|
||||
{
|
||||
"id": 901,
|
||||
"languageTag": "ar",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "arabic",
|
||||
@@ -460,6 +514,7 @@
|
||||
{
|
||||
"id": 1001,
|
||||
"languageTag": "hu",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "hungarian"
|
||||
@@ -468,6 +523,7 @@
|
||||
{
|
||||
"id": 1101,
|
||||
"languageTag": "eo",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "esperanto"
|
||||
@@ -476,6 +532,7 @@
|
||||
{
|
||||
"id": 1201,
|
||||
"languageTag": "hr",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwertz"
|
||||
@@ -484,6 +541,7 @@
|
||||
{
|
||||
"id": 1301,
|
||||
"languageTag": "ru",
|
||||
"composer": "appender",
|
||||
"currencySet": "russian_ruble",
|
||||
"preferred": {
|
||||
"characters": "jcuken_russian"
|
||||
@@ -492,6 +550,7 @@
|
||||
{
|
||||
"id": 1351,
|
||||
"languageTag": "uk",
|
||||
"composer": "appender",
|
||||
"currencySet": "ukrainian_hryvnia",
|
||||
"preferred": {
|
||||
"characters": "jcuken_ukrainian"
|
||||
@@ -500,6 +559,7 @@
|
||||
{
|
||||
"id": 1401,
|
||||
"languageTag": "el",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "greek"
|
||||
@@ -508,6 +568,7 @@
|
||||
{
|
||||
"id": 1501,
|
||||
"languageTag": "ro",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -516,6 +577,7 @@
|
||||
{
|
||||
"id": 1601,
|
||||
"languageTag": "pl",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -524,6 +586,7 @@
|
||||
{
|
||||
"id": 1701,
|
||||
"languageTag": "bg-bg",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "bulgarian_phonetic"
|
||||
@@ -532,6 +595,7 @@
|
||||
{
|
||||
"id": 1801,
|
||||
"languageTag": "tr",
|
||||
"composer": "appender",
|
||||
"currencySet": "turkish_lira",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -540,6 +604,7 @@
|
||||
{
|
||||
"id": 1901,
|
||||
"languageTag": "iw-IL",
|
||||
"composer": "appender",
|
||||
"currencySet": "israeli_new_shekel",
|
||||
"preferred": {
|
||||
"characters": "hebrew"
|
||||
@@ -548,6 +613,7 @@
|
||||
{
|
||||
"id": 2001,
|
||||
"languageTag": "ckb",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "kurdish",
|
||||
@@ -559,6 +625,7 @@
|
||||
{
|
||||
"id": 2101,
|
||||
"languageTag": "sr-RS",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "serbian_cyrillic"
|
||||
@@ -567,6 +634,7 @@
|
||||
{
|
||||
"id": 2201,
|
||||
"languageTag": "lv-LV",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
@@ -575,6 +643,7 @@
|
||||
{
|
||||
"id": 2301,
|
||||
"languageTag": "ku",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "kurdish_kurmanci"
|
||||
@@ -583,6 +652,7 @@
|
||||
{
|
||||
"id": 2501,
|
||||
"languageTag": "ca",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "catalan"
|
||||
@@ -591,6 +661,7 @@
|
||||
{
|
||||
"id": 2601,
|
||||
"languageTag": "IPA-IPA",
|
||||
"composer": "appender",
|
||||
"currencySet": "dollar",
|
||||
"preferred": {
|
||||
"characters": "ipa",
|
||||
@@ -601,6 +672,7 @@
|
||||
{
|
||||
"id": 2701,
|
||||
"languageTag": "sk",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwertz"
|
||||
@@ -609,10 +681,51 @@
|
||||
{
|
||||
"id": 2801,
|
||||
"languageTag": "cs",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwertz"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2900,
|
||||
"languageTag": "ko",
|
||||
"composer": "hangul-unicode",
|
||||
"currencySet": "south_korean_won",
|
||||
"preferred": {
|
||||
"characters": "korean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3000,
|
||||
"languageTag": "lt-LT",
|
||||
"composer": "appender",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwerty"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3100,
|
||||
"languageTag": "ja-JP-jis",
|
||||
"composer": "kana-unicode",
|
||||
"currencySet": "yen",
|
||||
"preferred": {
|
||||
"characters": "jis",
|
||||
"symbols": "cjk",
|
||||
"symbols2": "cjk",
|
||||
"numericRow": "cjk"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3200,
|
||||
"languageTag": "th-kd",
|
||||
"composer": "appender",
|
||||
"currencySet": "thai_baht",
|
||||
"preferred": {
|
||||
"characters": "thai_kedmanee",
|
||||
"numericRow": "thai"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
69
app/src/main/assets/ime/spelling/config.json
Normal file
69
app/src/main/assets/ime/spelling/config.json
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"basePath": "ime/spelling",
|
||||
"importSources": [
|
||||
{
|
||||
"id": "mozilla_firefox",
|
||||
"label": "Mozilla Firefox Add-ons",
|
||||
"url": "https://addons.mozilla.org/firefox/language-tools/",
|
||||
"format": {
|
||||
"$": "archive",
|
||||
"file": {
|
||||
"name": "^.+\\.xpi$",
|
||||
"isRequired": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "libre_office",
|
||||
"label": "LibreOffice [CURRENTLY UNSUPPORTED]",
|
||||
"url": "https://extensions.libreoffice.org/?Tags%5B%5D=50",
|
||||
"format": {
|
||||
"$": "archive",
|
||||
"file": {
|
||||
"name": "^.+\\.oxt$",
|
||||
"isRequired": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "open_office",
|
||||
"label": "Apache OpenOffice [CURRENTLY UNSUPPORTED]",
|
||||
"url": "https://extensions.openoffice.org/en/search?f%5B0%5D=field_project_tags%3A157",
|
||||
"format": {
|
||||
"$": "archive",
|
||||
"file": {
|
||||
"name": "^.+\\.oxt$",
|
||||
"isRequired": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "free_office",
|
||||
"label": "SoftMaker FreeOffice",
|
||||
"url": "https://www.freeoffice.com/en/download/dictionaries",
|
||||
"format": {
|
||||
"$": "archive",
|
||||
"file": {
|
||||
"name": "^.+\\.sox$",
|
||||
"isRequired": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gh_wooorm",
|
||||
"label": "GitHub collection by Titus Wormer",
|
||||
"url": "https://github.com/wooorm/dictionaries",
|
||||
"format": {
|
||||
"$": "raw",
|
||||
"affFile": {
|
||||
"name": "^.+\\.aff$",
|
||||
"isRequired": true
|
||||
},
|
||||
"dicFile": {
|
||||
"name": "^.+\\.dic$",
|
||||
"isRequired": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
61
app/src/main/assets/ime/text/characters/bone.json
Normal file
61
app/src/main/assets/ime/text/characters/bone.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "bone",
|
||||
"label": "Bone",
|
||||
"authors": [ "ostrya" ],
|
||||
"direction": "ltr",
|
||||
"modifier": "neo2",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "case_selector",
|
||||
"lower": {
|
||||
"code": 223, "label": "ß", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 180, "label": "´" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"upper": {
|
||||
"code": 7838, "label": "ẞ", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 180, "label": "´" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" }
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -4,59 +4,21 @@
|
||||
"authors": [ "HeiWiper" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
"ض": {
|
||||
"relevant": [
|
||||
{ "code": 1633, "label": "١" }
|
||||
]
|
||||
},
|
||||
"ص": {
|
||||
"relevant": [
|
||||
{ "code": 1634, "label": "٢" }
|
||||
]
|
||||
},
|
||||
"ث": {
|
||||
"relevant": [
|
||||
{ "code": 1635, "label": "٣" }
|
||||
]
|
||||
},
|
||||
"ق": {
|
||||
"relevant": [
|
||||
{ "code": 1704, "label": "ڨ" },
|
||||
{ "code": 1636, "label": "٤" }
|
||||
{ "code": 1704, "label": "ڨ" }
|
||||
]
|
||||
},
|
||||
"ف": {
|
||||
"relevant": [
|
||||
{ "code": 1701, "label": "ڥ" },
|
||||
{ "code": 1700, "label": "ڤ" },
|
||||
{ "code": 1698, "label": "ڢ" },
|
||||
{ "code": 1637, "label": "٥" }
|
||||
]
|
||||
},
|
||||
"غ": {
|
||||
"relevant": [
|
||||
{ "code": 1638, "label": "٦" }
|
||||
]
|
||||
},
|
||||
"ع": {
|
||||
"relevant": [
|
||||
{ "code": 1639, "label": "٧" }
|
||||
{ "code": 1698, "label": "ڢ" }
|
||||
]
|
||||
},
|
||||
"ه": {
|
||||
"relevant": [
|
||||
{ "code": 1726, "label": "ھ" },
|
||||
{ "code": 1640, "label": "٨" }
|
||||
]
|
||||
},
|
||||
"خ": {
|
||||
"relevant": [
|
||||
{ "code": 1641, "label": "٩" }
|
||||
]
|
||||
},
|
||||
"ح": {
|
||||
"relevant": [
|
||||
{ "code": 1632, "label": "٠" }
|
||||
{ "code": 1726, "label": "ھ" }
|
||||
]
|
||||
},
|
||||
"ج": {
|
||||
@@ -70,8 +32,8 @@
|
||||
]
|
||||
},
|
||||
"ي": {
|
||||
"main": { "code": 1574, "label": "ئ" },
|
||||
"relevant": [
|
||||
{ "code": 1574, "label": "ئ" },
|
||||
{ "code": 1609, "label": "ى" }
|
||||
]
|
||||
},
|
||||
@@ -89,10 +51,10 @@
|
||||
]
|
||||
},
|
||||
"ا": {
|
||||
"main": { "code": 1571, "label": "أ" },
|
||||
"relevant": [
|
||||
{ "code": 1570, "label": "آ" },
|
||||
{ "code": 1569, "label": "ء" },
|
||||
{ "code": 1571, "label": "أ" },
|
||||
{ "code": 1573, "label": "إ" },
|
||||
{ "code": 1649, "label": "ٱ" }
|
||||
]
|
||||
@@ -104,9 +66,7 @@
|
||||
]
|
||||
},
|
||||
"ى": {
|
||||
"relevant": [
|
||||
{ "code": 1574, "label": "ئ" }
|
||||
]
|
||||
"main": { "code": 1574, "label": "ئ" }
|
||||
},
|
||||
"ز": {
|
||||
"relevant": [
|
||||
|
||||
@@ -79,6 +79,9 @@
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"main": { "$": "auto_text_key", "code": 241, "label": "ñ" }
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
|
||||
@@ -4,28 +4,22 @@
|
||||
"authors": [ "GoRaN" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
|
||||
"ﻪ": {
|
||||
"relevant": [
|
||||
{ "code": 1577, "label": "ة" },
|
||||
{ "code": 1729, "label": "ـہ" }
|
||||
]
|
||||
},
|
||||
"ر": {
|
||||
"relevant": [
|
||||
{ "code": 1685, "label": "ڕ" },
|
||||
{ "code": 1682, "label": "ڒ" }
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
"ی": {
|
||||
"relevant": [
|
||||
{ "code": 1746, "label": "ے" },
|
||||
{ "code": 1610, "label": "ي" },
|
||||
{ "code": 1744, "label": "ې" },
|
||||
{ "code": 1741, "label": "ۍ" },
|
||||
{ "code": 1742, "label": "ێ" },
|
||||
{ "code": 1744, "label": "ې" },
|
||||
{ "code": 1610, "label": "ي" },
|
||||
{ "code": 1597, "label": "ؽ" }
|
||||
]
|
||||
},
|
||||
@@ -34,10 +28,15 @@
|
||||
"ﺋ": {
|
||||
"relevant": [
|
||||
{ "code": 65163, "label": "ﺋ" },
|
||||
{ "code": 1569, "label": "ء" },
|
||||
{ "code": 65139, "label": "ﹳ" }
|
||||
]
|
||||
},
|
||||
"ح": {
|
||||
"relevant": [
|
||||
{ "code": 65010, "label": "ﷲ" },
|
||||
{ "code": 65019, "label": "ﷻ" }
|
||||
]
|
||||
},
|
||||
|
||||
"ع": {
|
||||
"relevant": [
|
||||
@@ -56,12 +55,9 @@
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
"ف": {
|
||||
"relevant": [
|
||||
{ "code": 1701, "label": "ڥ" },
|
||||
{ "code": 1700, "label": "ڤ" },
|
||||
{ "code": 1698, "label": "ڢ" },
|
||||
{ "code": 1697, "label": "ڡ" }
|
||||
]
|
||||
@@ -70,7 +66,6 @@
|
||||
"د": {
|
||||
"relevant": [
|
||||
{ "code": 1676, "label": "ڌ" },
|
||||
{ "code": 1584, "label": "ذ" },
|
||||
{ "code": 64390, "label": "ﮆ" },
|
||||
{ "code": 1774, "label": "ۮ" }
|
||||
]
|
||||
@@ -93,9 +88,7 @@
|
||||
},
|
||||
"ب": {
|
||||
"relevant": [
|
||||
{ "code": 65010, "label": "ﷲ" },
|
||||
{ "code": 65021, "label": "﷽" },
|
||||
{ "code": 65019, "label": "ﷻ" }
|
||||
{ "code": 65021, "label": "﷽" }
|
||||
]
|
||||
},
|
||||
"م": {
|
||||
@@ -108,7 +101,6 @@
|
||||
"relevant": [
|
||||
{ "code": 1718, "label": "ڶ" },
|
||||
{ "code": 1719, "label": "ڷ" },
|
||||
{ "code": 1717, "label": "ڵ" },
|
||||
{ "code": 1720, "label": "ڸ" }
|
||||
]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"type": "characters/extended_popups",
|
||||
"name": "de-DE-neobone",
|
||||
"authors": [ "ostrya" ],
|
||||
"mapping": {
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".ch" },
|
||||
{ "code": -255, "label": ".de" },
|
||||
{ "code": -255, "label": ".at" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
]
|
||||
},
|
||||
"ι": {
|
||||
"main": { "$": "auto_text_key", "code": 943, "label": "ί" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 912, "label": "ΐ" },
|
||||
{ "$": "auto_text_key", "code": 970, "label": "ϊ" },
|
||||
{ "$": "auto_text_key", "code": 943, "label": "ί" }
|
||||
{ "$": "auto_text_key", "code": 970, "label": "ϊ" }
|
||||
]
|
||||
},
|
||||
"ο": {
|
||||
@@ -32,10 +32,10 @@
|
||||
]
|
||||
},
|
||||
"υ": {
|
||||
"main": { "$": "auto_text_key", "code": 973, "label": "ύ" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 944, "label": "ΰ" },
|
||||
{ "$": "auto_text_key", "code": 971, "label": "ϋ" },
|
||||
{ "$": "auto_text_key", "code": 973, "label": "ύ" }
|
||||
{ "$": "auto_text_key", "code": 971, "label": "ϋ" }
|
||||
]
|
||||
},
|
||||
"ω": {
|
||||
|
||||
@@ -0,0 +1,292 @@
|
||||
{
|
||||
"type": "characters/extended_popups",
|
||||
"name": "ja-JP-jis",
|
||||
"authors": [ "waelwindows" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
"あ": {
|
||||
"main": { "code": 12353, "label": "ぁ" }
|
||||
},
|
||||
"ア": {
|
||||
"main": { "code": 12449, "label": "ァ" }
|
||||
},
|
||||
"ア": {
|
||||
"main": { "code": 65383, "label": "ァ" }
|
||||
},
|
||||
"い": {
|
||||
"main": { "code": 12355, "label": "ぃ" },
|
||||
"relevant": [
|
||||
{ "code": 12432, "label": "ゐ" },
|
||||
{ "code": 110928, "label": "𛅐" }
|
||||
]
|
||||
},
|
||||
"イ": {
|
||||
"main": { "code": 12451, "label": "ィ" },
|
||||
"relevant": [
|
||||
{ "code": 12528, "label": "ヰ" },
|
||||
{ "code": 110948, "label": "𛅤" }
|
||||
]
|
||||
},
|
||||
"イ": {
|
||||
"main": { "code": 65384, "label": "ィ" }
|
||||
},
|
||||
"う": {
|
||||
"main": { "code": 12357, "label": "ぅ" }
|
||||
},
|
||||
"ウ": {
|
||||
"main": { "code": 12453, "label": "ゥ" }
|
||||
},
|
||||
"ウ": {
|
||||
"main": { "code": 65385, "label": "ゥ" }
|
||||
},
|
||||
"え": {
|
||||
"main": { "code": 12359, "label": "ぇ" },
|
||||
"relevant": [
|
||||
{ "code": 12433, "label": "ゑ" },
|
||||
{ "code": 110929, "label": "𛅑" }
|
||||
]
|
||||
},
|
||||
"エ": {
|
||||
"main": { "code": 12455, "label": "ェ" },
|
||||
"relevant": [
|
||||
{ "code": 12529, "label": "ヱ" },
|
||||
{ "code": 110949, "label": "𛅥" }
|
||||
]
|
||||
},
|
||||
"エ": {
|
||||
"main": { "code": 65386, "label": "ェ" }
|
||||
},
|
||||
"お": {
|
||||
"main": { "code": 12361, "label": "ぉ" }
|
||||
},
|
||||
"オ": {
|
||||
"main": { "code": 12457, "label": "ォ" }
|
||||
},
|
||||
"オ": {
|
||||
"main": { "code": 65387, "label": "ォ" }
|
||||
},
|
||||
"や": {
|
||||
"main": { "code": 12419, "label": "ゃ" }
|
||||
},
|
||||
"ヤ": {
|
||||
"main": { "code": 12515, "label": "ャ" }
|
||||
},
|
||||
"ヤ": {
|
||||
"main": { "code": 65388, "label": "ャ" }
|
||||
},
|
||||
"ゆ": {
|
||||
"main": { "code": 12421, "label": "ゅ" }
|
||||
},
|
||||
"ユ": {
|
||||
"main": { "code": 12517, "label": "ュ" }
|
||||
},
|
||||
"ユ": {
|
||||
"main": { "code": 65389, "label": "ュ" }
|
||||
},
|
||||
"よ": {
|
||||
"main": { "code": 12423, "label": "ょ" }
|
||||
},
|
||||
"ヨ": {
|
||||
"main": { "code": 12519, "label": "ョ" }
|
||||
},
|
||||
"ヨ": {
|
||||
"main": { "code": 65390, "label": "ョ" }
|
||||
},
|
||||
"わ": {
|
||||
"main": { "code": 12434, "label": "を" },
|
||||
"relevant": [
|
||||
{ "code": 12430, "label": "ゎ" },
|
||||
{ "code": 110930, "label": "𛅒" }
|
||||
]
|
||||
},
|
||||
"ワ": {
|
||||
"main": { "code": 12530, "label": "ヲ" },
|
||||
"relevant": [
|
||||
{ "code": 12526, "label": "ヮ" },
|
||||
{ "code": 110950, "label": "𛅦" }
|
||||
]
|
||||
},
|
||||
"ワ": {
|
||||
"main": { "code": 65382, "label": "ヲ" }
|
||||
},
|
||||
"つ": {
|
||||
"main": { "code": 12387, "label": "っ" }
|
||||
},
|
||||
"ツ": {
|
||||
"main": { "code": 12483, "label": "ッ" }
|
||||
},
|
||||
"ツ": {
|
||||
"main": { "code": 65391, "label": "ッ" }
|
||||
},
|
||||
"ト": {
|
||||
"relevant": [
|
||||
{ "code": 12787, "label": "ㇳ" }
|
||||
]
|
||||
},
|
||||
"シ": {
|
||||
"relevant": [
|
||||
{ "code": 12785, "label": "ㇱ" }
|
||||
]
|
||||
},
|
||||
"ス": {
|
||||
"main": { "code": 12786, "label": "ㇲ" }
|
||||
},
|
||||
"か": {
|
||||
"main": { "code": 12437, "label": "ゕ" }
|
||||
},
|
||||
"カ": {
|
||||
"main": { "code": 12533, "label": "ヵ" }
|
||||
},
|
||||
"ク": {
|
||||
"main": { "code": 12784, "label": "ㇰ" }
|
||||
},
|
||||
"け": {
|
||||
"main": { "code": 12438, "label": "ゖ" }
|
||||
},
|
||||
"ケ": {
|
||||
"main": { "code": 12534, "label": "ヶ" }
|
||||
},
|
||||
"ヌ": {
|
||||
"relevant": [
|
||||
{ "code": 12788, "label": "ㇴ" }
|
||||
]
|
||||
},
|
||||
"ハ": {
|
||||
"relevant": [
|
||||
{ "code": 12789, "label": "ㇵ" }
|
||||
]
|
||||
},
|
||||
"ヒ": {
|
||||
"relevant": [
|
||||
{ "code": 12790, "label": "ㇶ" }
|
||||
]
|
||||
},
|
||||
"フ": {
|
||||
"relevant": [
|
||||
{ "code": 12791, "label": "ㇷ" }
|
||||
]
|
||||
},
|
||||
"ヘ": {
|
||||
"relevant": [
|
||||
{ "code": 12792, "label": "ㇸ" }
|
||||
]
|
||||
},
|
||||
"ホ": {
|
||||
"relevant": [
|
||||
{ "code": 12793, "label": "ㇹ" }
|
||||
]
|
||||
},
|
||||
"ム": {
|
||||
"relevant": [
|
||||
{ "code": 12794, "label": "ㇺ" }
|
||||
]
|
||||
},
|
||||
"ラ": {
|
||||
"relevant": [
|
||||
{ "code": 12795, "label": "ㇻ" }
|
||||
]
|
||||
},
|
||||
"リ": {
|
||||
"relevant": [
|
||||
{ "code": 12796, "label": "ㇼ" }
|
||||
]
|
||||
},
|
||||
"ル": {
|
||||
"relevant": [
|
||||
{ "code": 12797, "label": "ㇽ" }
|
||||
]
|
||||
},
|
||||
"レ": {
|
||||
"relevant": [
|
||||
{ "code": 12798, "label": "ㇾ" }
|
||||
]
|
||||
},
|
||||
"ロ": {
|
||||
"relevant": [
|
||||
{ "code": 12799, "label": "ㇿ" }
|
||||
]
|
||||
},
|
||||
"゛": {
|
||||
"main": { "code": 12443, "label": "゛" }
|
||||
},
|
||||
"゜": {
|
||||
"main": { "code": 12444, "label": "゜" }
|
||||
},
|
||||
"~kana": {
|
||||
"relevant": [
|
||||
{ "code": -9711, "label": "あ" },
|
||||
{ "code": -9712, "label": "ア" },
|
||||
{ "code": -9713, "label": "ア" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "$": "char_width_selector",
|
||||
"full": { "code": 12539, "label": "・" },
|
||||
"half": { "code": 9834, "label": "♪" }
|
||||
},
|
||||
"relevant": [
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65286, "label": "&" },
|
||||
"half": { "code": 38, "label": "&" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65285, "label": "%" },
|
||||
"half": { "code": 37, "label": "%" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65291, "label": "+" },
|
||||
"half": { "code": 43, "label": "+" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65340, "label": "\" },
|
||||
"half": { "code": 92, "label": "\\" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65293, "label": "-" },
|
||||
"half": { "code": 45, "label": "-" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65306, "label": ":" },
|
||||
"half": { "code": 58, "label": ":" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65287, "label": "'" },
|
||||
"half": { "code": 39, "label": "'" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65312, "label": "@" },
|
||||
"half": { "code": 64, "label": "@" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65307, "label": ";" },
|
||||
"half": { "code": 59, "label": ";" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65295, "label": "/" },
|
||||
"half": { "code": 47, "label": "/" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65288, "label": "(" },
|
||||
"half": { "code": 40, "label": "(" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65289, "label": ")" },
|
||||
"half": { "code": 41, "label": ")" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65283, "label": "#" },
|
||||
"half": { "code": 35, "label": "#" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65281, "label": "!" },
|
||||
"half": { "code": 33, "label": "!" }
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65311, "label": "?" },
|
||||
"half": { "code": 63, "label": "?" }
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"type": "characters/extended_popups",
|
||||
"name": "ko",
|
||||
"authors": [ "patrickgold", "Hayleia" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
"ㅂ": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 12611, "label": "ㅃ" }
|
||||
]
|
||||
},
|
||||
"ㅈ": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 12617, "label": "ㅉ" }
|
||||
]
|
||||
},
|
||||
"ㄷ": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 12600, "label": "ㄸ" }
|
||||
]
|
||||
},
|
||||
"ㄱ": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 12594, "label": "ㄲ" }
|
||||
]
|
||||
},
|
||||
"ㅅ": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 12614, "label": "ㅆ" }
|
||||
]
|
||||
},
|
||||
"ㅐ": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 12626, "label": "ㅒ" }
|
||||
]
|
||||
},
|
||||
"ㅔ": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 12630, "label": "ㅖ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 37, "label": "%" },
|
||||
{ "code": 43, "label": "+" },
|
||||
{ "code": 34, "label": "\"" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 39, "label": "'" },
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 59, "label": ";" },
|
||||
{ "code": 47, "label": "/" },
|
||||
{ "code": 40, "label": "(" },
|
||||
{ "code": 41, "label": ")" },
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".gov" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
167
app/src/main/assets/ime/text/characters/extended_popups/lt.json
Normal file
167
app/src/main/assets/ime/text/characters/extended_popups/lt.json
Normal file
@@ -0,0 +1,167 @@
|
||||
{
|
||||
"type": "characters/extended_popups",
|
||||
"name": "lv",
|
||||
"authors": [ "patrickgold" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
"a": {
|
||||
"main": { "$": "auto_text_key", "code": 261, "label": "ą" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"main": { "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" },
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
]
|
||||
},
|
||||
"d": {
|
||||
"main": { "$": "auto_text_key", "code": 271, "label": "ď" }
|
||||
},
|
||||
"e": {
|
||||
"main": { "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 283, "label": "ě" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" }
|
||||
]
|
||||
},
|
||||
"g": {
|
||||
"main": { "$": "auto_text_key", "code": 291, "label": "ģ" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 287, "label": "ğ" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"main": { "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" }
|
||||
]
|
||||
},
|
||||
"k": {
|
||||
"main": { "$": "auto_text_key", "code": 311, "label": "ķ" }
|
||||
},
|
||||
"l": {
|
||||
"main": { "$": "auto_text_key", "code": 316, "label": "ļ" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 318, "label": "ľ" },
|
||||
{ "$": "auto_text_key", "code": 314, "label": "ĺ" },
|
||||
{ "$": "auto_text_key", "code": 322, "label": "ł" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"main": { "$": "auto_text_key", "code": 326, "label": "ņ" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" },
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"main": { "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 337, "label": "ő" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" }
|
||||
]
|
||||
},
|
||||
"r": {
|
||||
"main": { "$": "auto_text_key", "code": 343, "label": "ŗ" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 341, "label": "ŕ" },
|
||||
{ "$": "auto_text_key", "code": 345, "label": "ř" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"main": { "$": "auto_text_key", "code": 353, "label": "š" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" },
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" },
|
||||
{ "$": "auto_text_key", "code": 351, "label": "ş" }
|
||||
]
|
||||
},
|
||||
"t": {
|
||||
"main": { "$": "auto_text_key", "code": 355, "label": "ţ" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 357, "label": "ť" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"main": { "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 367, "label": "ů" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 369, "label": "ű" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 371, "label": "ų" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"main": { "$": "auto_text_key", "code": 253, "label": "ý" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 255, "label": "ÿ" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"main": { "$": "auto_text_key", "code": 382, "label": "ž" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 378, "label": "ź" },
|
||||
{ "$": "auto_text_key", "code": 380, "label": "ż" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 37, "label": "%" },
|
||||
{ "code": 43, "label": "+" },
|
||||
{ "code": 34, "label": "\"" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 39, "label": "'" },
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 59, "label": ";" },
|
||||
{ "code": 47, "label": "/" },
|
||||
{ "code": 40, "label": "(" },
|
||||
{ "code": 41, "label": ")" },
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".lv" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".gov" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
{ "code": -255, "label": ".com" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +1,35 @@
|
||||
{
|
||||
"type": "characters/extended_popups",
|
||||
"name": "tr",
|
||||
"authors": [ "kisekinopureya", "patrickgold" ],
|
||||
"authors": [ "kisekinopureya", "patrickgold", "dvrnynr" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"main": { "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 601, "label": "ə" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" }
|
||||
]
|
||||
"main": { "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
},
|
||||
"g": {
|
||||
"main": { "$": "auto_text_key", "code": 287, "label": "ğ" }
|
||||
},
|
||||
"i": {
|
||||
"main": { "$": "auto_text_key", "code": 305, "label": "ı" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
"main": { "$": "case_selector",
|
||||
"lower": { "code": 305, "label": "ı" },
|
||||
"upper": { "code": 73, "label": "I" }
|
||||
}
|
||||
},
|
||||
"ı": {
|
||||
"main": { "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 328, "label": "ň" },
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" }
|
||||
]
|
||||
"main": { "$": "case_selector",
|
||||
"lower": { "code": 105, "label": "i" },
|
||||
"upper": { "code": 304, "label": "İ" }
|
||||
}
|
||||
},
|
||||
"o": {
|
||||
"main": { "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" }
|
||||
]
|
||||
"main": { "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
},
|
||||
"s": {
|
||||
"main": { "$": "auto_text_key", "code": 351, "label": "ş" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" },
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" },
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
]
|
||||
"main": { "$": "auto_text_key", "code": 351, "label": "ş" }
|
||||
},
|
||||
"u": {
|
||||
"main": { "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 253, "label": "ý" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 382, "label": "ž" }
|
||||
]
|
||||
"main": { "$": "auto_text_key", "code": 252, "label": "ü" }
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
@@ -120,10 +56,10 @@
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".gov" },
|
||||
{ "code": -255, "label": ".gov.tr" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
{ "code": -255, "label": ".tr" },
|
||||
{ "code": -255, "label": ".edu.tr" },
|
||||
{ "code": -255, "label": ".com.tr" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
|
||||
77
app/src/main/assets/ime/text/characters/halmak.json
Normal file
77
app/src/main/assets/ime/text/characters/halmak.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "halmak",
|
||||
"label": "Halmak",
|
||||
"authors": [ "dessalines" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 59, "label": ";", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 58, "label": ":" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 58, "label": ":", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 59, "label": ";" }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 44, "label": ",", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 40, "label": "(" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 40, "label": "(", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 44, "label": "," }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 46, "label": ".", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 41, "label": ")" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 41, "label": ")", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 46, "label": "." }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" }
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -28,27 +28,27 @@
|
||||
{ "code": 1508, "label": "פ" }
|
||||
],
|
||||
[
|
||||
{ "code": 1513, "label": "ף" },
|
||||
{ "code": 1491, "label": "ך" },
|
||||
{ "code": 1490, "label": "ל" },
|
||||
{ "code": 1499, "label": "ח" },
|
||||
{ "code": 1506, "label": "י" },
|
||||
{ "code": 1497, "label": "ע" },
|
||||
{ "code": 1495, "label": "כ" },
|
||||
{ "code": 1500, "label": "ג" },
|
||||
{ "code": 1498, "label": "ד" },
|
||||
{ "code": 1507, "label": "ש" }
|
||||
{ "code": 1513, "label": "ש" },
|
||||
{ "code": 1491, "label": "ד" },
|
||||
{ "code": 1490, "label": "ג" },
|
||||
{ "code": 1499, "label": "כ" },
|
||||
{ "code": 1506, "label": "ע" },
|
||||
{ "code": 1497, "label": "י" },
|
||||
{ "code": 1495, "label": "ח" },
|
||||
{ "code": 1500, "label": "ל" },
|
||||
{ "code": 1498, "label": "ך" },
|
||||
{ "code": 1507, "label": "ף" }
|
||||
],
|
||||
[
|
||||
{ "code": 1494, "label": "ץ" },
|
||||
{ "code": 1505, "label": "ת" },
|
||||
{ "code": 1489, "label": "צ" },
|
||||
{ "code": 1492, "label": "מ" },
|
||||
{ "code": 1494, "label": "ז" },
|
||||
{ "code": 1505, "label": "ס" },
|
||||
{ "code": 1489, "label": "ב" },
|
||||
{ "code": 1492, "label": "ה" },
|
||||
{ "code": 1504, "label": "נ" },
|
||||
{ "code": 1502, "label": "ה" },
|
||||
{ "code": 1510, "label": "ב" },
|
||||
{ "code": 1514, "label": "ס" },
|
||||
{ "code": 1509, "label": "ז" }
|
||||
{ "code": 1502, "label": "מ" },
|
||||
{ "code": 1510, "label": "צ" },
|
||||
{ "code": 1514, "label": "ת" },
|
||||
{ "code": 1509, "label": "ץ" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
354
app/src/main/assets/ime/text/characters/jis.json
Normal file
354
app/src/main/assets/ime/text/characters/jis.json
Normal file
@@ -0,0 +1,354 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "jis",
|
||||
"label": "JIS",
|
||||
"authors": [ "waelwindows" ],
|
||||
"direction": "ltr",
|
||||
"modifier": "jis",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12396, "label": "ぬ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12492, "label": "ヌ" },
|
||||
"half": { "code": 65415, "label": "ヌ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12405, "label": "ふ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12501, "label": "フ" },
|
||||
"half": { "code": 65420, "label": "フ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12354, "label": "あ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12450, "label": "ア" },
|
||||
"half": { "code": 65393, "label": "ア" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12358, "label": "う" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12454, "label": "ウ" },
|
||||
"half": { "code": 65395, "label": "ウ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12360, "label": "え" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12456, "label": "エ" },
|
||||
"half": { "code": 65396, "label": "エ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12362, "label": "お" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12458, "label": "オ" },
|
||||
"half": { "code": 65397, "label": "オ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12420, "label": "や" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12516, "label": "ヤ" },
|
||||
"half": { "code": 65428, "label": "ヤ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12422, "label": "ゆ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12518, "label": "ユ" },
|
||||
"half": { "code": 65429, "label": "ユ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12424, "label": "よ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12520, "label": "ヨ" },
|
||||
"half": { "code": 65430, "label": "ヨ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12431, "label": "わ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12527, "label": "ワ" },
|
||||
"half": { "code": 65436, "label": "ワ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12411, "label": "ほ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12507, "label": "ホ" },
|
||||
"half": { "code": 65422, "label": "ホ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12408, "label": "へ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12504, "label": "ヘ" },
|
||||
"half": { "code": 65421, "label": "ヘ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12540, "label": "ー" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12540, "label": "ー" },
|
||||
"half": { "code": 65392, "label": "ー" }
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12383, "label": "た" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12479, "label": "タ" },
|
||||
"half": { "code": 65408, "label": "タ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12390, "label": "て" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12486, "label": "テ" },
|
||||
"half": { "code": 65411, "label": "テ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12356, "label": "い" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12452, "label": "イ" },
|
||||
"half": { "code": 65394, "label": "イ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12377, "label": "す" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12473, "label": "ス" },
|
||||
"half": { "code": 65405, "label": "ス" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12363, "label": "か" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12459, "label": "カ" },
|
||||
"half": { "code": 65398, "label": "カ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12435, "label": "ん" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12531, "label": "ン" },
|
||||
"half": { "code": 65437, "label": "ン" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12394, "label": "な" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12490, "label": "ナ" },
|
||||
"half": { "code": 65413, "label": "ナ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12395, "label": "に" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12491, "label": "ニ" },
|
||||
"half": { "code": 65414, "label": "ニ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12425, "label": "ら" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12521, "label": "ラ" },
|
||||
"half": { "code": 65431, "label": "ラ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12379, "label": "せ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12475, "label": "セ" },
|
||||
"half": { "code": 65406, "label": "セ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12441, "label": "゛" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12441, "label": "゛" },
|
||||
"half": { "code": 65438, "label": "゙" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12442, "label": "゜" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12442, "label": "゜" },
|
||||
"half": { "code": 65439, "label": "゚" }
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12385, "label": "ち" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12481, "label": "チ" },
|
||||
"half": { "code": 65409, "label": "チ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12392, "label": "と" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12488, "label": "ト" },
|
||||
"half": { "code": 65412, "label": "ト" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12375, "label": "し" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12471, "label": "シ" },
|
||||
"half": { "code": 65410, "label": "シ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12399, "label": "は" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12495, "label": "ハ" },
|
||||
"half": { "code": 65418, "label": "ハ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12365, "label": "き" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12461, "label": "キ" },
|
||||
"half": { "code": 65399, "label": "キ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12367, "label": "く" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12463, "label": "ク" },
|
||||
"half": { "code": 65400, "label": "ク" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12414, "label": "ま" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12510, "label": "マ" },
|
||||
"half": { "code": 65423, "label": "マ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12398, "label": "の" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12494, "label": "ノ" },
|
||||
"half": { "code": 65417, "label": "ノ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12426, "label": "り" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12522, "label": "リ" },
|
||||
"half": { "code": 65432, "label": "リ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12428, "label": "れ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12524, "label": "レ" },
|
||||
"half": { "code": 65434, "label": "レ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12369, "label": "け" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12465, "label": "ケ" },
|
||||
"half": { "code": 65401, "label": "ケ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12416, "label": "む" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12512, "label": "ム" },
|
||||
"half": { "code": 65425, "label": "ム" }
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12388, "label": "つ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12484, "label": "ツ" },
|
||||
"half": { "code": 65410, "label": "ツ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12373, "label": "さ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12469, "label": "サ" },
|
||||
"half": { "code": 65403, "label": "サ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12381, "label": "そ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12477, "label": "ソ" },
|
||||
"half": { "code": 65407, "label": "ソ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12402, "label": "ひ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12498, "label": "ヒ" },
|
||||
"half": { "code": 65419, "label": "ヒ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12371, "label": "こ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12467, "label": "コ" },
|
||||
"half": { "code": 65402, "label": "コ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12415, "label": "み" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12511, "label": "ミ" },
|
||||
"half": { "code": 65424, "label": "ミ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12418, "label": "も" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12514, "label": "モ" },
|
||||
"half": { "code": 65427, "label": "モ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12397, "label": "ね" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12493, "label": "ネ" },
|
||||
"half": { "code": 65416, "label": "ネ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12427, "label": "る" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12523, "label": "ル" },
|
||||
"half": { "code": 65433, "label": "ル" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12417, "label": "め" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12513, "label": "メ" },
|
||||
"half": { "code": 65426, "label": "メ" }
|
||||
}
|
||||
},
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12429, "label": "ろ" },
|
||||
"kata": { "$": "char_width_selector",
|
||||
"full": { "code": 12525, "label": "ロ" },
|
||||
"half": { "code": 65435, "label": "ロ" }
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
62
app/src/main/assets/ime/text/characters/korean.json
Normal file
62
app/src/main/assets/ime/text/characters/korean.json
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "korean",
|
||||
"label": "South Korean standard",
|
||||
"authors": [ "patrickgold", "Hayleia" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 12610, "label": "ㅂ" },
|
||||
"upper": { "code": 12611, "label": "ㅃ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 12616, "label": "ㅈ" },
|
||||
"upper": { "code": 12617, "label": "ㅉ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 12599, "label": "ㄷ" },
|
||||
"upper": { "code": 12600, "label": "ㄸ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 12593, "label": "ㄱ" },
|
||||
"upper": { "code": 12594, "label": "ㄲ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 12613, "label": "ㅅ" },
|
||||
"upper": { "code": 12614, "label": "ㅆ" }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 12635, "label": "ㅛ"},
|
||||
{ "$": "auto_text_key", "code": 12629, "label": "ㅕ"},
|
||||
{ "$": "auto_text_key", "code": 12625, "label": "ㅑ"},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 12624, "label": "ㅐ" },
|
||||
"upper": { "code": 12626, "label": "ㅒ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 12628, "label": "ㅔ" },
|
||||
"upper": { "code": 12630, "label": "ㅖ" }
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 12609, "label": "ㅁ"},
|
||||
{ "$": "auto_text_key", "code": 12596, "label": "ㄴ"},
|
||||
{ "$": "auto_text_key", "code": 12615, "label": "ㅇ"},
|
||||
{ "$": "auto_text_key", "code": 12601, "label": "ㄹ"},
|
||||
{ "$": "auto_text_key", "code": 12622, "label": "ㅎ"},
|
||||
{ "$": "auto_text_key", "code": 12631, "label": "ㅗ"},
|
||||
{ "$": "auto_text_key", "code": 12627, "label": "ㅓ"},
|
||||
{ "$": "auto_text_key", "code": 12623, "label": "ㅏ"},
|
||||
{ "$": "auto_text_key", "code": 12643, "label": "ㅣ"}
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 12619, "label": "ㅋ"},
|
||||
{ "$": "auto_text_key", "code": 12620, "label": "ㅌ"},
|
||||
{ "$": "auto_text_key", "code": 12618, "label": "ㅊ"},
|
||||
{ "$": "auto_text_key", "code": 12621, "label": "ㅍ"},
|
||||
{ "$": "auto_text_key", "code": 12640, "label": "ㅠ"},
|
||||
{ "$": "auto_text_key", "code": 12636, "label": "ㅜ"},
|
||||
{ "$": "auto_text_key", "code": 12641, "label": "ㅡ"}
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "kurdish",
|
||||
"label": "کوردی",
|
||||
"label": "کوردی (قوەرتی نوێ)",
|
||||
"authors": [ "GoRaN" ],
|
||||
"direction": "rtl",
|
||||
"modifier": "kurdish",
|
||||
@@ -13,34 +13,46 @@
|
||||
{ "code": 1608, "label": "و", "popup": {
|
||||
"main": { "code": -255, "label": "وو" }
|
||||
} },
|
||||
{ "code": 1749, "label": "ﻪ" },
|
||||
{ "code": 1585, "label": "ر" },
|
||||
|
||||
{ "code": 1749, "label": "ﻪ", "popup": {
|
||||
"main": { "code": 1577, "label": "ة" }
|
||||
} },
|
||||
{ "code": 1585, "label": "ر", "popup": {
|
||||
"main": { "code": 1685, "label": "ڕ" }
|
||||
} },
|
||||
{ "code": 1578, "label": "ت", "popup": {
|
||||
"main": { "code": 1591, "label": "ط" }
|
||||
} },
|
||||
{ "code": 1740, "label": "ی" },
|
||||
|
||||
{ "code": 1574, "label": "ﺋ"},
|
||||
|
||||
{ "code": 1740, "label": "ی", "popup": {
|
||||
"main": { "code": 1742, "label": "ێ" }
|
||||
} },
|
||||
{ "code": 1574, "label": "ﺋ", "popup": {
|
||||
"main": { "code": 1569, "label": "ء" }
|
||||
} },
|
||||
{ "code": 1593, "label": "ع", "popup": {
|
||||
"main": { "code": 1594, "label": "غ" }
|
||||
} },
|
||||
{ "code": 1734, "label": "ۆ" },
|
||||
|
||||
{ "code": 1662, "label": "پ", "popup": {
|
||||
"main": { "code": 1579, "label": "ث" }
|
||||
} }
|
||||
],
|
||||
[
|
||||
{ "code": 1575, "label": "ا" },
|
||||
{"code": 1575, "label": "ا"},
|
||||
{ "code": 1587, "label": "س" },
|
||||
{ "code": 1588, "label": "ش" },
|
||||
{ "code": 1583, "label": "د" },
|
||||
{ "code": 1601, "label": "ف" },
|
||||
{ "code": 1583, "label": "د", "popup": {
|
||||
"main": {"code": 1584, "label": "ذ" }
|
||||
} },
|
||||
{ "code": 1601, "label": "ف" , "popup": {
|
||||
"main": {"code": 1700, "label": "ڤ" }
|
||||
} },
|
||||
{ "code": 1607, "label": "ھ" },
|
||||
{ "code": 1688, "label": "ژ" },
|
||||
{ "code": 1604, "label": "ل" },
|
||||
{ "code": 1688, "label": "ژ", "popup": {
|
||||
"main": { "code": 1600, "label": "▬" }
|
||||
} },
|
||||
{ "code": 1604, "label": "ل", "popup": {
|
||||
"main": { "code": 1717, "label": "ڵ" }
|
||||
} },
|
||||
{ "code": 1705, "label": "ک" },
|
||||
{ "code": 1711, "label": "گ" }
|
||||
],
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 305, "label": "ı" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "kurdish_standard",
|
||||
"label": "کوردی - ستاندارد",
|
||||
"label": "کوردی (قڤفغ)",
|
||||
"authors": [ "GoRaN" ],
|
||||
"direction": "rtl",
|
||||
"modifier": "kurdish",
|
||||
@@ -10,16 +10,14 @@
|
||||
{ "code": 1602, "label": "ق", "popup": {
|
||||
"main": { "code": 1647, "label": "ٯ" }
|
||||
} },
|
||||
{ "code": 1700, "label": "ڤ", "popup": {
|
||||
"main": { "code": 1701, "label": "ڥ" }
|
||||
} },
|
||||
{ "code": 1601, "label": "ف", "popup": {
|
||||
"main": { "code": 1698, "label": "ڢ" }
|
||||
} },
|
||||
{ "code": 1700, "label": "ڤ" },
|
||||
{ "code": 1601, "label": "ف" },
|
||||
{ "code": 1594, "label": "غ" },
|
||||
{ "code": 1593, "label": "ع"},
|
||||
{ "code": 1607, "label": "ھ" },
|
||||
{ "code": 1749, "label": "ﻪ" },
|
||||
{ "code": 1749, "label": "ﻪ", "popup": {
|
||||
"main": { "code": 1577, "label": "ة" }
|
||||
} },
|
||||
|
||||
{ "code": 1578, "label": "ت", "popup": {
|
||||
"main": { "code": 1591, "label": "ط" }
|
||||
@@ -46,7 +44,9 @@
|
||||
} },
|
||||
{ "code": 1585, "label": "ر" },
|
||||
{ "code": 1685, "label": "ڕ" },
|
||||
{ "code": 1583, "label": "د" },
|
||||
{ "code": 1583, "label": "د", "popup": {
|
||||
"main": {"code": 1584, "label": "ذ" }
|
||||
} },
|
||||
{ "code": -255, "label": "وو" },
|
||||
{ "code": 1608, "label": "و" },
|
||||
{ "code": 1734, "label": "ۆ" },
|
||||
@@ -55,8 +55,10 @@
|
||||
|
||||
],
|
||||
[
|
||||
{ "code": 1600, "label": "kashida", "variation": "normal" },
|
||||
{ "code": 1574, "label": "ﺋ"},
|
||||
|
||||
{ "code": 1574, "label": "ﺋ", "popup": {
|
||||
"main": { "code": 1569, "label": "ء" }
|
||||
} },
|
||||
|
||||
{ "code": 1662, "label": "پ", "popup": {
|
||||
"main": { "code": 1579, "label": "ث" }
|
||||
|
||||
29
app/src/main/assets/ime/text/characters/mod/jis.json
Normal file
29
app/src/main/assets/ime/text/characters/mod/jis.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"type": "characters/mod",
|
||||
"name": "jis",
|
||||
"label": "JIS",
|
||||
"authors": [ "waelwindows" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -5, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 12289, "label": "、", "groupId": 1 },
|
||||
"half": { "code": 65380, "label": "、", "groupId": 1 }
|
||||
},
|
||||
{ "code": -210, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -213, "label": "switch_to_media_context", "type": "system_gui" },
|
||||
{ "code": 12288, "label": "空白" },
|
||||
{ "code": -9710, "label": "かな", "groupId": 97, "type": "system_gui" },
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 12290, "label": "。", "groupId": 2 },
|
||||
"half": { "code": 65377, "label": "。", "groupId": 2 }
|
||||
},
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -6,14 +6,17 @@
|
||||
"direction": "rtl",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 1600, "label": "kashida", "popup":
|
||||
{ "main": { "code": 8204, "label": "half_space" }
|
||||
} },
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -5, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 1567, "label": "؟", "groupId": 1 },
|
||||
"password": { "code": 1548, "label": "،", "groupId": 1 },
|
||||
"default": { "code": 1548, "label": "،", "groupId": 1 },
|
||||
"password": { "code": 35, "label": "#", "groupId": 1 },
|
||||
"email": { "code": 64, "label": "@", "groupId": 1 },
|
||||
"uri": { "code": 47, "label": "/", "groupId": 1 }
|
||||
},
|
||||
|
||||
53
app/src/main/assets/ime/text/characters/mod/neo2.json
Normal file
53
app/src/main/assets/ime/text/characters/mod/neo2.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"type": "characters/mod",
|
||||
"name": "neo2",
|
||||
"label": "Neo2",
|
||||
"authors": [ "ostrya" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": -1, "label": "shift", "type": "modifier" },
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -5, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "code": -210, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -213, "label": "switch_to_media_context", "type": "system_gui" },
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 44, "label": ",", "groupId": 1,
|
||||
"popup": {
|
||||
"main": { "code": 34, "label": "\"" },
|
||||
"relevant": [
|
||||
{ "code": 8211, "label": "–" }
|
||||
]
|
||||
} },
|
||||
"email": { "code": 64, "label": "@", "groupId": 1,
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 44, "label": "," }
|
||||
]
|
||||
} },
|
||||
"uri": { "code": 47, "label": "/", "groupId": 1,
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 44, "label": "," }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 46, "label": ".", "groupId": 2,
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 183, "label": "·" },
|
||||
{ "code": 39, "label": "'" }
|
||||
]
|
||||
} },
|
||||
"email": { "code": 46, "label": ".", "groupId": 2 },
|
||||
"uri": { "code": 46, "label": ".", "groupId": 2 }
|
||||
},
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
}
|
||||
41
app/src/main/assets/ime/text/characters/nalmy.json
Normal file
41
app/src/main/assets/ime/text/characters/nalmy.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "nalmy",
|
||||
"label": "NALMY",
|
||||
"authors": [ "jeremiah-mille", "jasmcole" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" }
|
||||
]
|
||||
]
|
||||
}
|
||||
61
app/src/main/assets/ime/text/characters/neo2.json
Normal file
61
app/src/main/assets/ime/text/characters/neo2.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "neo2",
|
||||
"label": "Neo2",
|
||||
"authors": [ "ostrya" ],
|
||||
"direction": "ltr",
|
||||
"modifier": "neo2",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "case_selector",
|
||||
"lower": {
|
||||
"code": 223, "label": "ß", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 180, "label": "´" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"upper": {
|
||||
"code": 7838, "label": "ẞ", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 180, "label": "´" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" }
|
||||
]
|
||||
]
|
||||
}
|
||||
41
app/src/main/assets/ime/text/characters/sangaline.json
Normal file
41
app/src/main/assets/ime/text/characters/sangaline.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "sangaline",
|
||||
"label": "Sangaline",
|
||||
"authors": [ "jeremiah-miller", "sangaline" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" }
|
||||
]
|
||||
]
|
||||
}
|
||||
201
app/src/main/assets/ime/text/characters/thai_kedmanee.json
Normal file
201
app/src/main/assets/ime/text/characters/thai_kedmanee.json
Normal file
@@ -0,0 +1,201 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "thai_kedmanee",
|
||||
"label": "Thai Kedmanee",
|
||||
"authors": [ "mrdeck4rd" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3653, "label": "ๅ" },
|
||||
"upper": { "code": 43, "label": "+" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 47, "label": "/" },
|
||||
"upper": { "code": 3665, "label": "๑" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 95, "label": "_" },
|
||||
"upper": { "code": 3666, "label": "๒" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3616, "label": "ภ" },
|
||||
"upper": { "code": 3667, "label": "๓" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3606, "label": "ถ" },
|
||||
"upper": { "code": 3668, "label": "๔" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3640, "label": "ุ" },
|
||||
"upper": { "code": 3641, "label": "ู" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3638, "label": "ึ" },
|
||||
"upper": { "code": 3647, "label": "฿" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3588, "label": "ค" },
|
||||
"upper": { "code": 3669, "label": "๕" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3605, "label": "ต" },
|
||||
"upper": { "code": 3670, "label": "๖" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3592, "label": "จ" },
|
||||
"upper": { "code": 3671, "label": "๗" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3586, "label": "ข" },
|
||||
"upper": { "code": 3672, "label": "๘" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3594, "label": "ช" },
|
||||
"upper": { "code": 3673, "label": "๙" }
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3654, "label": "ๆ" },
|
||||
"upper": { "code": 3664, "label": "๐" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3652, "label": "ไ" },
|
||||
"upper": { "code": 34, "label": "\"" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3635, "label": "ำ" },
|
||||
"upper": { "code": 3598, "label": "ฎ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3614, "label": "พ" },
|
||||
"upper": { "code": 3601, "label": "ฑ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3632, "label": "ะ" },
|
||||
"upper": { "code": 3608, "label": "ธ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3633, "label": "ั" },
|
||||
"upper": { "code": 3661, "label": "ํ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3637, "label": "ี" },
|
||||
"upper": { "code": 3658, "label": "๊" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3619, "label": "ร" },
|
||||
"upper": { "code": 3603, "label": "ณ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3609, "label": "น" },
|
||||
"upper": { "code": 3631, "label": "ฯ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3618, "label": "ย" },
|
||||
"upper": { "code": 3597, "label": "ญ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3610, "label": "บ" },
|
||||
"upper": { "code": 3600, "label": "ฐ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3621, "label": "ล" },
|
||||
"upper": { "code": 44, "label": "," }
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3615, "label": "ฟ" },
|
||||
"upper": { "code": 3620, "label": "ฤ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3627, "label": "ห" },
|
||||
"upper": { "code": 3590, "label": "ฆ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3585, "label": "ก" },
|
||||
"upper": { "code": 3599, "label": "ฏ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3604, "label": "ด" },
|
||||
"upper": { "code": 3650, "label": "โ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3648, "label": "เ" },
|
||||
"upper": { "code": 3596, "label": "ฌ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3657, "label": "้" },
|
||||
"upper": { "code": 3655, "label": "็" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3656, "label": "่" },
|
||||
"upper": { "code": 3659, "label": "๋" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3634, "label": "า" },
|
||||
"upper": { "code": 3625, "label": "ษ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3626, "label": "ส" },
|
||||
"upper": { "code": 3624, "label": "ศ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3623, "label": "ว" },
|
||||
"upper": { "code": 3595, "label": "ซ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3591, "label": "ง" },
|
||||
"upper": { "code": 46, "label": "." }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3587, "label": "ฃ" },
|
||||
"upper": { "code": 3589, "label": "ฅ" }
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3612, "label": "ผ" },
|
||||
"upper": { "code": 40, "label": "(" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3611, "label": "ป" },
|
||||
"upper": { "code": 41, "label": ")" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3649, "label": "แ" },
|
||||
"upper": { "code": 3593, "label": "ฉ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3629, "label": "อ" },
|
||||
"upper": { "code": 3630, "label": "ฮ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3636, "label": "ิ" },
|
||||
"upper": { "code": 3642, "label": "ฺ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3639, "label": "ื" },
|
||||
"upper": { "code": 3660, "label": "์" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3607, "label": "ท" },
|
||||
"upper": { "code": 63, "label": "?" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3617, "label": "ม" },
|
||||
"upper": { "code": 3602, "label": "ฒ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3651, "label": "ใ" },
|
||||
"upper": { "code": 3628, "label": "ฬ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3613, "label": "ฝ" },
|
||||
"upper": { "code": 3622, "label": "ฦ" }
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
151
app/src/main/assets/ime/text/characters/thai_manoonchai.json
Normal file
151
app/src/main/assets/ime/text/characters/thai_manoonchai.json
Normal file
@@ -0,0 +1,151 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "thai_manoonchai",
|
||||
"label": "Thai Manoonchai",
|
||||
"authors": [ "mrdeck4rd" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3651, "label": "ใ" },
|
||||
"upper": { "code": 3602, "label": "ฒ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3605, "label": "ต" },
|
||||
"upper": { "code": 3599, "label": "ฏ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3627, "label": "ห" },
|
||||
"upper": { "code": 3595, "label": "ซ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3621, "label": "ล" },
|
||||
"upper": { "code": 3597, "label": "ญ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3626, "label": "ส" },
|
||||
"upper": { "code": 3615, "label": "ฟ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3611, "label": "ป" },
|
||||
"upper": { "code": 3593, "label": "ฉ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3633, "label": "ั" },
|
||||
"upper": { "code": 3638, "label": "ึ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3585, "label": "ก" },
|
||||
"upper": { "code": 3608, "label": "ธ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3636, "label": "ิ" },
|
||||
"upper": { "code": 3600, "label": "ฐ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3610, "label": "บ" },
|
||||
"upper": { "code": 3598, "label": "ฎ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3655, "label": "็" },
|
||||
"upper": { "code": 3590, "label": "ฆ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3628, "label": "ฬ" },
|
||||
"upper": { "code": 3601, "label": "ฑ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3631, "label": "ฯ" },
|
||||
"upper": { "code": 3596, "label": "ฌ" }
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3591, "label": "ง" },
|
||||
"upper": { "code": 3625, "label": "ษ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3648, "label": "เ" },
|
||||
"upper": { "code": 3606, "label": "ถ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3619, "label": "ร" },
|
||||
"upper": { "code": 3649, "label": "แ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3609, "label": "น" },
|
||||
"upper": { "code": 3594, "label": "ช" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3617, "label": "ม" },
|
||||
"upper": { "code": 3614, "label": "พ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3629, "label": "อ" },
|
||||
"upper": { "code": 3612, "label": "ผ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3634, "label": "า" },
|
||||
"upper": { "code": 3635, "label": "ำ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3656, "label": "่" },
|
||||
"upper": { "code": 3586, "label": "ข" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3657, "label": "้" },
|
||||
"upper": { "code": 3650, "label": "โ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3623, "label": "ว" },
|
||||
"upper": { "code": 3616, "label": "ภ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3639, "label": "ื" },
|
||||
"upper": { "code": 34, "label": "\"" }
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3640, "label": "ุ" },
|
||||
"upper": { "code": 3620, "label": "ฤ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3652, "label": "ไ" },
|
||||
"upper": { "code": 3613, "label": "ฝ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3607, "label": "ท" },
|
||||
"upper": { "code": 3654, "label": "ๆ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3618, "label": "ย" },
|
||||
"upper": { "code": 3603, "label": "ณ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3592, "label": "จ" },
|
||||
"upper": { "code": 3658, "label": "๊" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3588, "label": "ค" },
|
||||
"upper": { "code": 3659, "label": "๋" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3637, "label": "ี" },
|
||||
"upper": { "code": 3660, "label": "์" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3604, "label": "ด" },
|
||||
"upper": { "code": 3624, "label": "ศ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3632, "label": "ะ" },
|
||||
"upper": { "code": 3630, "label": "ฮ" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 3641, "label": "ู" },
|
||||
"upper": { "code": 63, "label": "?" }
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -9,7 +9,10 @@
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 287, "label": "ğ" },
|
||||
{ "$": "auto_text_key", "code": 305, "label": "ı" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 305, "label": "ı" },
|
||||
"upper": { "code": 73, "label": "I" }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
@@ -21,7 +24,10 @@
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 105, "label": "i" },
|
||||
"upper": { "code": 304, "label": "İ" }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 305, "label": "ı" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 305, "label": "ı" },
|
||||
"upper": { "code": 73, "label": "I" }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 287, "label": "ğ" },
|
||||
@@ -30,7 +33,10 @@
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 351, "label": "ş" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" }
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 105, "label": "i" },
|
||||
"upper": { "code": 304, "label": "İ" }
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"type": "numeric_advanced",
|
||||
"name": "western_arabic_pc",
|
||||
"label": "Western Arabic (PC)",
|
||||
"authors": [ "patrickgold" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 43, "label": "+", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 42, "label": "*" },
|
||||
{ "code": 47, "label": "/" }
|
||||
]
|
||||
} },
|
||||
{ "code": 55, "label": "7", "type": "numeric" },
|
||||
{ "code": 56, "label": "8", "type": "numeric" },
|
||||
{ "code": 57, "label": "9", "type": "numeric" },
|
||||
{ "code": 37, "label": "%" }
|
||||
],
|
||||
[
|
||||
{ "code": 40, "label": "(", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 91, "label": "[" },
|
||||
{ "code": 123, "label": "{" }
|
||||
]
|
||||
} },
|
||||
{ "code": 52, "label": "4", "type": "numeric" },
|
||||
{ "code": 53, "label": "5", "type": "numeric" },
|
||||
{ "code": 54, "label": "6", "type": "numeric" },
|
||||
{ "code": 32, "label": "space" }
|
||||
],
|
||||
[
|
||||
{ "code": 41, "label": ")", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 93, "label": "]" },
|
||||
{ "code": 125, "label": "}" }
|
||||
]
|
||||
} },
|
||||
{ "code": 49, "label": "1", "type": "numeric" },
|
||||
{ "code": 50, "label": "2", "type": "numeric" },
|
||||
{ "code": 51, "label": "3", "type": "numeric" },
|
||||
{ "code": -5, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -201, "label": "view_characters", "type": "system_gui" },
|
||||
{ "code": 44, "label": "," },
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "code": 48, "label": "0", "type": "numeric" },
|
||||
{ "code": 61, "label": "=" },
|
||||
{ "code": 46, "label": "." },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
}
|
||||
91
app/src/main/assets/ime/text/numeric/row/bengali.json
Normal file
91
app/src/main/assets/ime/text/numeric/row/bengali.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "bengali",
|
||||
"label": "Bengali",
|
||||
"authors": [ "yashpalgoyal1304" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 2535, "label": "১", "type": "numeric", "popup": {
|
||||
"main": { "code": 49, "label": "1" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 185, "label": "¹" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2536, "label": "২", "type": "numeric", "popup": {
|
||||
"main": { "code": 50, "label": "2" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 178, "label": "²" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2537, "label": "৩", "type": "numeric", "popup": {
|
||||
"main": { "code": 51, "label": "3" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 179, "label": "³" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2538, "label": "৪", "type": "numeric", "popup": {
|
||||
"main": { "code": 52, "label": "4" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" },
|
||||
{ "code": 8308, "label": "⁴" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2539, "label": "৫", "type": "numeric", "popup": {
|
||||
"main": { "code": 53, "label": "5" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8309, "label": "⁵" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2540, "label": "৬", "type": "numeric", "popup": {
|
||||
"main": { "code": 54, "label": "6" },
|
||||
"relevant": [
|
||||
{ "code": 8310, "label": "⁶" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2541, "label": "৭", "type": "numeric", "popup": {
|
||||
"main": { "code": 55, "label": "7" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" },
|
||||
{ "code": 8311, "label": "⁷" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2542, "label": "৮", "type": "numeric", "popup": {
|
||||
"main": { "code": 56, "label": "8" },
|
||||
"relevant": [
|
||||
{ "code": 8312, "label": "⁸" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2543, "label": "৯", "type": "numeric", "popup": {
|
||||
"main": { "code": 57, "label": "9" },
|
||||
"relevant": [
|
||||
{ "code": 8313, "label": "⁹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2534, "label": "০", "type": "numeric", "popup": {
|
||||
"main": { "code": 48, "label": "0" },
|
||||
"relevant": [
|
||||
{ "code": 8319, "label": "ⁿ" },
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8304, "label": "⁰" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
108
app/src/main/assets/ime/text/numeric/row/cjk.json
Normal file
108
app/src/main/assets/ime/text/numeric/row/cjk.json
Normal file
@@ -0,0 +1,108 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "cjk",
|
||||
"label": "CJK",
|
||||
"authors": [ "waelwindows" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 19968, "label": "一", "type": "numeric", "popup": {
|
||||
"main": { "code": 49, "label": "1" },
|
||||
"relevant": [
|
||||
{ "code": 22769, "label": "壱" },
|
||||
{ "code": 22777, "label": "壹" },
|
||||
{ "code": 24332, "label": "弌" },
|
||||
{ "code": 65297, "label": "1" }
|
||||
]
|
||||
} },
|
||||
{ "code": 20108, "label": "二", "type": "numeric", "popup": {
|
||||
"main": { "code": 50, "label": "2" },
|
||||
"relevant": [
|
||||
{ "code": 24336, "label": "弐" },
|
||||
{ "code": 36019, "label": "貳" },
|
||||
{ "code": 36014, "label": "貮" },
|
||||
{ "code": 65298, "label": "2" }
|
||||
]
|
||||
} },
|
||||
{ "code": 19977, "label": "三", "type": "numeric", "popup": {
|
||||
"main": { "code": 51, "label": "3" },
|
||||
"relevant": [
|
||||
{ "code": 21442, "label": "参" },
|
||||
{ "code": 21443, "label": "參" },
|
||||
{ "code": 24334, "label": "弎" },
|
||||
{ "code": 65299, "label": "3" }
|
||||
]
|
||||
} },
|
||||
{ "code": 22235, "label": "四", "type": "numeric", "popup": {
|
||||
"main": { "code": 52, "label": "4" },
|
||||
"relevant": [
|
||||
{ "code": 32902, "label": "肆" },
|
||||
{ "code": 18825, "label": "䦉" },
|
||||
{ "code": 20118, "label": "亖" },
|
||||
{ "code": 65300, "label": "3" }
|
||||
]
|
||||
} },
|
||||
{ "code": 20116, "label": "五", "type": "numeric", "popup": {
|
||||
"main": { "code": 53, "label": "5" },
|
||||
"relevant": [
|
||||
{ "code": 20237, "label": "伍" },
|
||||
{ "code": 65301, "label": "5" }
|
||||
]
|
||||
} },
|
||||
{ "code": 20845, "label": "六", "type": "numeric", "popup": {
|
||||
"main": { "code": 54, "label": "6" },
|
||||
"relevant": [
|
||||
{ "code": 38520, "label": "陸" },
|
||||
{ "code": 65302, "label": "6" }
|
||||
]
|
||||
} },
|
||||
{ "code": 19971, "label": "七", "type": "numeric", "popup": {
|
||||
"main": { "code": 55, "label": "7" },
|
||||
"relevant": [
|
||||
{ "code": 28422, "label": "漆" },
|
||||
{ "code": 26578, "label": "柒" },
|
||||
{ "code": 65303, "label": "7" }
|
||||
]
|
||||
} },
|
||||
{ "code": 20843, "label": "八", "type": "numeric", "popup": {
|
||||
"main": { "code": 56, "label": "8" },
|
||||
"relevant": [
|
||||
{ "code": 25420, "label": "捌" },
|
||||
{ "code": 65304, "label": "8" }
|
||||
]
|
||||
} },
|
||||
{ "code": 20061, "label": "九", "type": "numeric", "popup": {
|
||||
"main": {"code": 57, "label": "9" },
|
||||
"relevant": [
|
||||
{ "code": 29590, "label": "玖" },
|
||||
{ "code": 65305, "label": "9" }
|
||||
]
|
||||
} },
|
||||
{ "code": 38646, "label": "零", "type": "numeric", "popup": {
|
||||
"main": { "code": 48, "label": "0" },
|
||||
"relevant": [
|
||||
{ "code": 12295, "label": "〇" },
|
||||
{ "code": 65296, "label": "0" }
|
||||
]
|
||||
} },
|
||||
{ "code": 21313, "label": "十", "type": "numeric", "popup": {
|
||||
"main": { "code": 25342, "label": "拾" },
|
||||
"relevant": [
|
||||
{ "code": 20160, "label": "什" }
|
||||
]
|
||||
} },
|
||||
{ "code": 30334, "label": "百", "type": "numeric", "popup": {
|
||||
"main": { "code": 20336, "label": "佰" },
|
||||
"relevant": [
|
||||
{ "code": 38476, "label": "陌" }
|
||||
]
|
||||
} },
|
||||
{ "code": 21315, "label": "千", "type": "numeric", "popup": {
|
||||
"main": { "code": 20191, "label": "仟" },
|
||||
"relevant": [
|
||||
{ "code": 38433, "label": "阡" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
91
app/src/main/assets/ime/text/numeric/row/devanagari.json
Normal file
91
app/src/main/assets/ime/text/numeric/row/devanagari.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "devanagari",
|
||||
"label": "Devanagari",
|
||||
"authors": [ "yashpalgoyal1304" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 2407, "label": "१", "type": "numeric", "popup": {
|
||||
"main": { "code": 49, "label": "1" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 185, "label": "¹" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2408, "label": "२", "type": "numeric", "popup": {
|
||||
"main": { "code": 50, "label": "2" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 178, "label": "²" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2409, "label": "३", "type": "numeric", "popup": {
|
||||
"main": { "code": 51, "label": "3" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 179, "label": "³" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2410, "label": "४", "type": "numeric", "popup": {
|
||||
"main": { "code": 52, "label": "4" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" },
|
||||
{ "code": 8308, "label": "⁴" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2411, "label": "५", "type": "numeric", "popup": {
|
||||
"main": { "code": 53, "label": "5" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8309, "label": "⁵" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2412, "label": "६", "type": "numeric", "popup": {
|
||||
"main": { "code": 54, "label": "6" },
|
||||
"relevant": [
|
||||
{ "code": 8310, "label": "⁶" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2413, "label": "७", "type": "numeric", "popup": {
|
||||
"main": { "code": 55, "label": "7" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" },
|
||||
{ "code": 8311, "label": "⁷" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2414, "label": "८", "type": "numeric", "popup": {
|
||||
"main": { "code": 56, "label": "8" },
|
||||
"relevant": [
|
||||
{ "code": 8312, "label": "⁸" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2415, "label": "९", "type": "numeric", "popup": {
|
||||
"main": { "code": 57, "label": "9" },
|
||||
"relevant": [
|
||||
{ "code": 8313, "label": "⁹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2406, "label": "०", "type": "numeric", "popup": {
|
||||
"main": { "code": 48, "label": "0" },
|
||||
"relevant": [
|
||||
{ "code": 8319, "label": "ⁿ" },
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8304, "label": "⁰" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
91
app/src/main/assets/ime/text/numeric/row/gujarati.json
Normal file
91
app/src/main/assets/ime/text/numeric/row/gujarati.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "gujarati",
|
||||
"label": "Gujarati",
|
||||
"authors": [ "yashpalgoyal1304" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 2791, "label": "૧", "type": "numeric", "popup": {
|
||||
"main": { "code": 49, "label": "1" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 185, "label": "¹" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2792, "label": "૨", "type": "numeric", "popup": {
|
||||
"main": { "code": 50, "label": "2" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 178, "label": "²" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2793, "label": "૩", "type": "numeric", "popup": {
|
||||
"main": { "code": 51, "label": "3" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 179, "label": "³" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2794, "label": "૪", "type": "numeric", "popup": {
|
||||
"main": { "code": 52, "label": "4" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" },
|
||||
{ "code": 8308, "label": "⁴" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2795, "label": "૫", "type": "numeric", "popup": {
|
||||
"main": { "code": 53, "label": "5" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8309, "label": "⁵" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2796, "label": "૬", "type": "numeric", "popup": {
|
||||
"main": { "code": 54, "label": "6" },
|
||||
"relevant": [
|
||||
{ "code": 8310, "label": "⁶" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2797, "label": "૭", "type": "numeric", "popup": {
|
||||
"main": { "code": 55, "label": "7" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" },
|
||||
{ "code": 8311, "label": "⁷" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2798, "label": "૮", "type": "numeric", "popup": {
|
||||
"main": { "code": 56, "label": "8" },
|
||||
"relevant": [
|
||||
{ "code": 8312, "label": "⁸" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2799, "label": "૯", "type": "numeric", "popup": {
|
||||
"main": { "code": 57, "label": "9" },
|
||||
"relevant": [
|
||||
{ "code": 8313, "label": "⁹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2790, "label": "૦", "type": "numeric", "popup": {
|
||||
"main": { "code": 48, "label": "0" },
|
||||
"relevant": [
|
||||
{ "code": 8319, "label": "ⁿ" },
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8304, "label": "⁰" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
91
app/src/main/assets/ime/text/numeric/row/gurmukhi.json
Normal file
91
app/src/main/assets/ime/text/numeric/row/gurmukhi.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "gurmukhi",
|
||||
"label": "Gurmukhi",
|
||||
"authors": [ "yashpalgoyal1304" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 2663, "label": "੧", "type": "numeric", "popup": {
|
||||
"main": { "code": 49, "label": "1" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 185, "label": "¹" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2664, "label": "੨", "type": "numeric", "popup": {
|
||||
"main": { "code": 50, "label": "2" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 178, "label": "²" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2665, "label": "੩", "type": "numeric", "popup": {
|
||||
"main": { "code": 51, "label": "3" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 179, "label": "³" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2666, "label": "੪", "type": "numeric", "popup": {
|
||||
"main": { "code": 52, "label": "4" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" },
|
||||
{ "code": 8308, "label": "⁴" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2667, "label": "੫", "type": "numeric", "popup": {
|
||||
"main": { "code": 53, "label": "5" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8309, "label": "⁵" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2668, "label": "੬", "type": "numeric", "popup": {
|
||||
"main": { "code": 54, "label": "6" },
|
||||
"relevant": [
|
||||
{ "code": 8310, "label": "⁶" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2669, "label": "੭", "type": "numeric", "popup": {
|
||||
"main": { "code": 55, "label": "7" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" },
|
||||
{ "code": 8311, "label": "⁷" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2670, "label": "੮", "type": "numeric", "popup": {
|
||||
"main": { "code": 56, "label": "8" },
|
||||
"relevant": [
|
||||
{ "code": 8312, "label": "⁸" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2671, "label": "੯", "type": "numeric", "popup": {
|
||||
"main": { "code": 57, "label": "9" },
|
||||
"relevant": [
|
||||
{ "code": 8313, "label": "⁹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2662, "label": "੦", "type": "numeric", "popup": {
|
||||
"main": { "code": 48, "label": "0" },
|
||||
"relevant": [
|
||||
{ "code": 8319, "label": "ⁿ" },
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8304, "label": "⁰" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
91
app/src/main/assets/ime/text/numeric/row/kannada.json
Normal file
91
app/src/main/assets/ime/text/numeric/row/kannada.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "kannada",
|
||||
"label": "Kannada",
|
||||
"authors": [ "yashpalgoyal1304" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 3303, "label": "೧", "type": "numeric", "popup": {
|
||||
"main": { "code": 49, "label": "1" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 185, "label": "¹" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3304, "label": "೨", "type": "numeric", "popup": {
|
||||
"main": { "code": 50, "label": "2" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 178, "label": "²" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3305, "label": "೩", "type": "numeric", "popup": {
|
||||
"main": { "code": 51, "label": "3" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 179, "label": "³" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3306, "label": "೪", "type": "numeric", "popup": {
|
||||
"main": { "code": 52, "label": "4" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" },
|
||||
{ "code": 8308, "label": "⁴" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3307, "label": "೫", "type": "numeric", "popup": {
|
||||
"main": { "code": 53, "label": "5" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8309, "label": "⁵" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3308, "label": "೬", "type": "numeric", "popup": {
|
||||
"main": { "code": 54, "label": "6" },
|
||||
"relevant": [
|
||||
{ "code": 8310, "label": "⁶" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3309, "label": "೭", "type": "numeric", "popup": {
|
||||
"main": { "code": 55, "label": "7" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" },
|
||||
{ "code": 8311, "label": "⁷" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3310, "label": "೮", "type": "numeric", "popup": {
|
||||
"main": { "code": 56, "label": "8" },
|
||||
"relevant": [
|
||||
{ "code": 8312, "label": "⁸" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3311, "label": "೯", "type": "numeric", "popup": {
|
||||
"main": { "code": 57, "label": "9" },
|
||||
"relevant": [
|
||||
{ "code": 8313, "label": "⁹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3302, "label": "೦", "type": "numeric", "popup": {
|
||||
"main": { "code": 48, "label": "0" },
|
||||
"relevant": [
|
||||
{ "code": 8319, "label": "ⁿ" },
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8304, "label": "⁰" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
91
app/src/main/assets/ime/text/numeric/row/malayalam.json
Normal file
91
app/src/main/assets/ime/text/numeric/row/malayalam.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "malayalam",
|
||||
"label": "Malayalam",
|
||||
"authors": [ "yashpalgoyal1304" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 3431, "label": "൧", "type": "numeric", "popup": {
|
||||
"main": { "code": 49, "label": "1" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 185, "label": "¹" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3432, "label": "൨", "type": "numeric", "popup": {
|
||||
"main": { "code": 50, "label": "2" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 178, "label": "²" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3433, "label": "൩", "type": "numeric", "popup": {
|
||||
"main": { "code": 51, "label": "3" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 179, "label": "³" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3434, "label": "൪", "type": "numeric", "popup": {
|
||||
"main": { "code": 52, "label": "4" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" },
|
||||
{ "code": 8308, "label": "⁴" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3435, "label": "൫", "type": "numeric", "popup": {
|
||||
"main": { "code": 53, "label": "5" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8309, "label": "⁵" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3436, "label": "൬", "type": "numeric", "popup": {
|
||||
"main": { "code": 54, "label": "6" },
|
||||
"relevant": [
|
||||
{ "code": 8310, "label": "⁶" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3437, "label": "൭", "type": "numeric", "popup": {
|
||||
"main": { "code": 55, "label": "7" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" },
|
||||
{ "code": 8311, "label": "⁷" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3438, "label": "൮", "type": "numeric", "popup": {
|
||||
"main": { "code": 56, "label": "8" },
|
||||
"relevant": [
|
||||
{ "code": 8312, "label": "⁸" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3439, "label": "൯", "type": "numeric", "popup": {
|
||||
"main": { "code": 57, "label": "9" },
|
||||
"relevant": [
|
||||
{ "code": 8313, "label": "⁹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3430, "label": "൦", "type": "numeric", "popup": {
|
||||
"main": { "code": 48, "label": "0" },
|
||||
"relevant": [
|
||||
{ "code": 8319, "label": "ⁿ" },
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8304, "label": "⁰" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
80
app/src/main/assets/ime/text/numeric/row/neo2.json
Normal file
80
app/src/main/assets/ime/text/numeric/row/neo2.json
Normal file
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "neo2",
|
||||
"label": "Neo2",
|
||||
"authors": [ "ostrya" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 49, "label": "1", "type": "numeric", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 176, "label": "°" },
|
||||
{ "code": 185, "label": "¹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 50, "label": "2", "type": "numeric", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 167, "label": "§" },
|
||||
{ "code": 178, "label": "²" }
|
||||
]
|
||||
} },
|
||||
{ "code": 51, "label": "3", "type": "numeric", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 8467, "label": "ℓ" },
|
||||
{ "code": 179, "label": "³" }
|
||||
]
|
||||
} },
|
||||
{ "code": 52, "label": "4", "type": "numeric", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 187, "label": "»" },
|
||||
{ "code": 8250, "label": "›" }
|
||||
]
|
||||
} },
|
||||
{ "code": 53, "label": "5", "type": "numeric", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 171, "label": "«" },
|
||||
{ "code": 8249, "label": "‹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 54, "label": "6", "type": "numeric", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 36, "label": "$" },
|
||||
{ "code": 162, "label": "¢" }
|
||||
]
|
||||
} },
|
||||
{ "code": 55, "label": "7", "type": "numeric", "popup": {
|
||||
"main": { "code": -801, "label": "currency_slot_1" },
|
||||
"relevant": [
|
||||
{ "code": -802, "label": "currency_slot_2" },
|
||||
{ "code": -803, "label": "currency_slot_3" },
|
||||
{ "code": -804, "label": "currency_slot_4" },
|
||||
{ "code": -805, "label": "currency_slot_5" },
|
||||
{ "code": -806, "label": "currency_slot_6" }
|
||||
]
|
||||
} },
|
||||
{ "code": 56, "label": "8", "type": "numeric", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 8222, "label": "„" },
|
||||
{ "code": 8218, "label": "‚" }
|
||||
]
|
||||
} },
|
||||
{ "code": 57, "label": "9", "type": "numeric", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 8220, "label": "“" },
|
||||
{ "code": 8216, "label": "‘" }
|
||||
]
|
||||
} },
|
||||
{ "code": 48, "label": "0", "type": "numeric", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 8221, "label": "”" },
|
||||
{ "code": 8217, "label": "’" }
|
||||
]
|
||||
} },
|
||||
{ "code": 45, "label": "-", "type": "numeric", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 8212, "label": "—" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
91
app/src/main/assets/ime/text/numeric/row/oriya.json
Normal file
91
app/src/main/assets/ime/text/numeric/row/oriya.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "oriya",
|
||||
"label": "Odia",
|
||||
"authors": [ "yashpalgoyal1304" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 2919, "label": "୧", "type": "numeric", "popup": {
|
||||
"main": { "code": 49, "label": "1" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 185, "label": "¹" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2920, "label": "୨", "type": "numeric", "popup": {
|
||||
"main": { "code": 50, "label": "2" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 178, "label": "²" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2921, "label": "୩", "type": "numeric", "popup": {
|
||||
"main": { "code": 51, "label": "3" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 179, "label": "³" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2922, "label": "୪", "type": "numeric", "popup": {
|
||||
"main": { "code": 52, "label": "4" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" },
|
||||
{ "code": 8308, "label": "⁴" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2923, "label": "୫", "type": "numeric", "popup": {
|
||||
"main": { "code": 53, "label": "5" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8309, "label": "⁵" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2924, "label": "୬", "type": "numeric", "popup": {
|
||||
"main": { "code": 54, "label": "6" },
|
||||
"relevant": [
|
||||
{ "code": 8310, "label": "⁶" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2925, "label": "୭", "type": "numeric", "popup": {
|
||||
"main": { "code": 55, "label": "7" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" },
|
||||
{ "code": 8311, "label": "⁷" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2926, "label": "୮", "type": "numeric", "popup": {
|
||||
"main": { "code": 56, "label": "8" },
|
||||
"relevant": [
|
||||
{ "code": 8312, "label": "⁸" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2927, "label": "୯", "type": "numeric", "popup": {
|
||||
"main": { "code": 57, "label": "9" },
|
||||
"relevant": [
|
||||
{ "code": 8313, "label": "⁹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 2918, "label": "୦", "type": "numeric", "popup": {
|
||||
"main": { "code": 48, "label": "0" },
|
||||
"relevant": [
|
||||
{ "code": 8319, "label": "ⁿ" },
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8304, "label": "⁰" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
91
app/src/main/assets/ime/text/numeric/row/tamil.json
Normal file
91
app/src/main/assets/ime/text/numeric/row/tamil.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "tamil",
|
||||
"label": "Tamil",
|
||||
"authors": [ "yashpalgoyal1304" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 3047, "label": "௧", "type": "numeric", "popup": {
|
||||
"main": { "code": 49, "label": "1" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 185, "label": "¹" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3048, "label": "௨", "type": "numeric", "popup": {
|
||||
"main": { "code": 50, "label": "2" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 178, "label": "²" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3049, "label": "௩", "type": "numeric", "popup": {
|
||||
"main": { "code": 51, "label": "3" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 179, "label": "³" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3050, "label": "௪", "type": "numeric", "popup": {
|
||||
"main": { "code": 52, "label": "4" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" },
|
||||
{ "code": 8308, "label": "⁴" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3051, "label": "௫", "type": "numeric", "popup": {
|
||||
"main": { "code": 53, "label": "5" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8309, "label": "⁵" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3052, "label": "௬", "type": "numeric", "popup": {
|
||||
"main": { "code": 54, "label": "6" },
|
||||
"relevant": [
|
||||
{ "code": 8310, "label": "⁶" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3053, "label": "௭", "type": "numeric", "popup": {
|
||||
"main": { "code": 55, "label": "7" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" },
|
||||
{ "code": 8311, "label": "⁷" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3054, "label": "௮", "type": "numeric", "popup": {
|
||||
"main": { "code": 56, "label": "8" },
|
||||
"relevant": [
|
||||
{ "code": 8312, "label": "⁸" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3055, "label": "௯", "type": "numeric", "popup": {
|
||||
"main": { "code": 57, "label": "9" },
|
||||
"relevant": [
|
||||
{ "code": 8313, "label": "⁹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3046, "label": "௦", "type": "numeric", "popup": {
|
||||
"main": { "code": 48, "label": "0" },
|
||||
"relevant": [
|
||||
{ "code": 8319, "label": "ⁿ" },
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8304, "label": "⁰" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
91
app/src/main/assets/ime/text/numeric/row/telugu.json
Normal file
91
app/src/main/assets/ime/text/numeric/row/telugu.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "telugu",
|
||||
"label": "Telugu",
|
||||
"authors": [ "yashpalgoyal1304" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 3175, "label": "౧", "type": "numeric", "popup": {
|
||||
"main": { "code": 49, "label": "1" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 185, "label": "¹" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3176, "label": "౨", "type": "numeric", "popup": {
|
||||
"main": { "code": 50, "label": "2" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 178, "label": "²" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3177, "label": "౩", "type": "numeric", "popup": {
|
||||
"main": { "code": 51, "label": "3" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 179, "label": "³" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3178, "label": "౪", "type": "numeric", "popup": {
|
||||
"main": { "code": 52, "label": "4" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" },
|
||||
{ "code": 8308, "label": "⁴" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3179, "label": "౫", "type": "numeric", "popup": {
|
||||
"main": { "code": 53, "label": "5" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8309, "label": "⁵" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3180, "label": "౬", "type": "numeric", "popup": {
|
||||
"main": { "code": 54, "label": "6" },
|
||||
"relevant": [
|
||||
{ "code": 8310, "label": "⁶" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3181, "label": "౭", "type": "numeric", "popup": {
|
||||
"main": { "code": 55, "label": "7" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" },
|
||||
{ "code": 8311, "label": "⁷" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3182, "label": "౮", "type": "numeric", "popup": {
|
||||
"main": { "code": 56, "label": "8" },
|
||||
"relevant": [
|
||||
{ "code": 8312, "label": "⁸" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3183, "label": "౯", "type": "numeric", "popup": {
|
||||
"main": { "code": 57, "label": "9" },
|
||||
"relevant": [
|
||||
{ "code": 8313, "label": "⁹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3174, "label": "౦", "type": "numeric", "popup": {
|
||||
"main": { "code": 48, "label": "0" },
|
||||
"relevant": [
|
||||
{ "code": 8319, "label": "ⁿ" },
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8304, "label": "⁰" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
75
app/src/main/assets/ime/text/numeric/row/thai.json
Normal file
75
app/src/main/assets/ime/text/numeric/row/thai.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"type": "numeric_row",
|
||||
"name": "thai",
|
||||
"label": "Thai",
|
||||
"authors": [ "mrdeck4rd" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 3665, "label": "๑", "type": "numeric", "popup": {
|
||||
"main": { "code": 185, "label": "¹" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3666, "label": "๒", "type": "numeric", "popup": {
|
||||
"main": { "code": 178, "label": "²" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3667, "label": "๓", "type": "numeric", "popup": {
|
||||
"main": { "code": 179, "label": "³" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3668, "label": "๔", "type": "numeric", "popup": {
|
||||
"main": { "code": 8308, "label": "⁴" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3669, "label": "๕", "type": "numeric", "popup": {
|
||||
"main": { "code": 8309, "label": "⁵" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3670, "label": "๖", "type": "numeric", "popup": {
|
||||
"main": { "code": 8310, "label": "⁶" }
|
||||
} },
|
||||
{ "code": 3671, "label": "๗", "type": "numeric", "popup": {
|
||||
"main": { "code": 8311, "label": "⁷" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" }
|
||||
]
|
||||
} },
|
||||
{ "code": 3672, "label": "๘", "type": "numeric", "popup": {
|
||||
"main": { "code": 8312, "label": "⁸" }
|
||||
} },
|
||||
{ "code": 3672, "label": "๘", "type": "numeric", "popup": {
|
||||
"main": { "code": 8313, "label": "⁹" }
|
||||
} },
|
||||
{ "code": 3664, "label": "๐", "type": "numeric", "popup": {
|
||||
"main": { "code": 8304, "label": "⁰" },
|
||||
"relevant": [
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8319, "label": "ⁿ" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
35
app/src/main/assets/ime/text/numeric/western_arabic_pc.json
Normal file
35
app/src/main/assets/ime/text/numeric/western_arabic_pc.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"type": "numeric",
|
||||
"name": "western_arabic_pc",
|
||||
"label": "Western Arabic (PC)",
|
||||
"authors": [ "patrickgold" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 55, "label": "7", "type": "numeric" },
|
||||
{ "code": 56, "label": "8", "type": "numeric" },
|
||||
{ "code": 57, "label": "9", "type": "numeric" },
|
||||
{ "code": 45, "label": "-" }
|
||||
],
|
||||
[
|
||||
{ "code": 52, "label": "4", "type": "numeric" },
|
||||
{ "code": 53, "label": "5", "type": "numeric" },
|
||||
{ "code": 54, "label": "6", "type": "numeric" },
|
||||
{ "code": 32, "label": "space" }
|
||||
],
|
||||
[
|
||||
{ "code": 49, "label": "1", "type": "numeric" },
|
||||
{ "code": 50, "label": "2", "type": "numeric" },
|
||||
{ "code": 51, "label": "3", "type": "numeric" },
|
||||
{ "code": -5, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": 44, "label": "," },
|
||||
{ "code": 48, "label": "0", "type": "numeric", "popup": {
|
||||
"main": { "code": 43, "label": "+" }
|
||||
} },
|
||||
{ "code": 46, "label": "." },
|
||||
{ "code": 10, "label": "enter", "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
}
|
||||
283
app/src/main/assets/ime/text/symbols/cjk.json
Normal file
283
app/src/main/assets/ime/text/symbols/cjk.json
Normal file
@@ -0,0 +1,283 @@
|
||||
{
|
||||
"type": "symbols",
|
||||
"name": "cjk",
|
||||
"label": "CJK",
|
||||
"authors": [ "waelwindows" ],
|
||||
"direction": "ltr",
|
||||
"modifier": "cjk",
|
||||
"arrangement": [
|
||||
[
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65312, "label": "@", "popup": {
|
||||
"main": { "code": 64, "label": "@" }
|
||||
}
|
||||
},
|
||||
"half": { "code": 64, "label": "@" }
|
||||
},
|
||||
{ "code": 12306, "label": "〒", "popup": {
|
||||
"main": { "code": 12320, "label": "〠" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65283, "label": "#", "popup": {
|
||||
"main": { "code": 35, "label": "#" },
|
||||
"relevant": [
|
||||
{ "code": 8470, "label": "№" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 35, "label": "#", "popup": {
|
||||
"main": { "code": 65283, "label": "#" },
|
||||
"relevant": [
|
||||
{ "code": 8470, "label": "№" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "code": -801, "label": "currency_slot_1", "popup": {
|
||||
"main": { "code": -802, "label": "currency_slot_2" },
|
||||
"relevant": [
|
||||
{ "code": -806, "label": "currency_slot_6" },
|
||||
{ "code": -803, "label": "currency_slot_3" },
|
||||
{ "code": -804, "label": "currency_slot_4" },
|
||||
{ "code": -805, "label": "currency_slot_5" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65285, "label": "%", "popup": {
|
||||
"main": { "code": 37, "label": "%" },
|
||||
"relevant": [
|
||||
{ "code": 8240, "label": "‰" },
|
||||
{ "code": 8453, "label": "℅" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 37, "label": "%", "popup": {
|
||||
"main": { "code": 65285, "label": "%" },
|
||||
"relevant": [
|
||||
{ "code": 8240, "label": "‰" },
|
||||
{ "code": 8453, "label": "℅" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65286, "label": "&", "popup": {
|
||||
"main": { "code": 38, "label": "&" }
|
||||
}
|
||||
},
|
||||
"half": { "code": 38, "label": "&", "popup": {
|
||||
"main": { "code": 65286, "label": "&" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65293, "label": "-", "popup": {
|
||||
"main": { "code": 65343, "label": "_" },
|
||||
"relevant": [
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 95, "label": "_" },
|
||||
{ "code": 8212, "label": "—" },
|
||||
{ "code": 8211, "label": "–" },
|
||||
{ "code": 183, "label": "·" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 45, "label": "-", "popup": {
|
||||
"main": { "code": 95, "label": "_" },
|
||||
"relevant": [
|
||||
{ "code": 65293, "label": "-" },
|
||||
{ "code": 65343, "label": "_" },
|
||||
{ "code": 8212, "label": "—" },
|
||||
{ "code": 8211, "label": "–" },
|
||||
{ "code": 183, "label": "·" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65291, "label": "+", "popup": {
|
||||
"main": { "code": 43, "label": "+" },
|
||||
"relevant": [
|
||||
{ "code": 177, "label": "±" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 43, "label": "+", "popup": {
|
||||
"main": { "code": 65291, "label": "+" },
|
||||
"relevant": [
|
||||
{ "code": 177, "label": "±" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 12300, "label": "「", "popup": {
|
||||
"main": { "code": 12302, "label": "『" },
|
||||
"relevant": [
|
||||
{ "code": 12304, "label": "【" },
|
||||
{ "code": 12310, "label": "〖" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 65378, "label": "「", "popup": {
|
||||
"main": { "code": 12301, "label": "」" },
|
||||
"relevant": [
|
||||
{ "code": 12303, "label": "』" },
|
||||
{ "code": 12304, "label": "【" },
|
||||
{ "code": 12310, "label": "〖" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 12301, "label": "」", "popup": {
|
||||
"main": { "code": 12303, "label": "』" },
|
||||
"relevant": [
|
||||
{ "code": 12305, "label": "】" },
|
||||
{ "code": 12311, "label": "〗" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 65379, "label": "」", "popup": {
|
||||
"main": { "code": 12301, "label": "」" },
|
||||
"relevant": [
|
||||
{ "code": 12303, "label": "』" },
|
||||
{ "code": 12305, "label": "】" },
|
||||
{ "code": 12311, "label": "〗" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65295, "label": "/", "popup": {
|
||||
"main": { "code": 47, "label": "/" }
|
||||
}
|
||||
},
|
||||
"half": { "code": 47, "label": "/", "popup": {
|
||||
"main": { "code": 65295, "label": "/" }
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65290, "label": "*", "popup": {
|
||||
"main": { "code": 8251, "label": "※" },
|
||||
"relevant": [
|
||||
{ "code": 42, "label": "*" },
|
||||
{ "code": 8224, "label": "†" },
|
||||
{ "code": 9733, "label": "★" },
|
||||
{ "code": 8225, "label": "‡" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 42, "label": "*", "popup": {
|
||||
"main": { "code": 65290, "label": "*" },
|
||||
"relevant": [
|
||||
{ "code": 8251, "label": "※" },
|
||||
{ "code": 8224, "label": "†" },
|
||||
{ "code": 9733, "label": "★" },
|
||||
{ "code": 8225, "label": "‡" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "code": 34, "label": "\"", "popup": {
|
||||
"main": { "code": 8221, "label": "”" },
|
||||
"relevant": [
|
||||
{ "code": 8222, "label": "„" },
|
||||
{ "code": 8220, "label": "“" },
|
||||
{ "code": 171, "label": "«" },
|
||||
{ "code": 187, "label": "»" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ "code": 39, "label": "'", "popup": {
|
||||
"main": { "code": 8217, "label": "’" },
|
||||
"relevant": [
|
||||
{ "code": 8218, "label": "‚" },
|
||||
{ "code": 8216, "label": "‘" },
|
||||
{ "code": 8249, "label": "‹" },
|
||||
{ "code": 8250, "label": "›" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65306, "label": ":", "popup": {
|
||||
"main": { "code": 58, "label": ":" },
|
||||
"relevant": [
|
||||
{ "code": 8942, "label": "⋮" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 58, "label": ":", "popup": {
|
||||
"main": { "code": 65306, "label": ":" },
|
||||
"relevant": [
|
||||
{ "code": 8942, "label": "⋮" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65307, "label": ";", "popup": {
|
||||
"main": { "code": 59, "label": ";" }
|
||||
}
|
||||
},
|
||||
"half": { "code": 59, "label": ";", "popup": {
|
||||
"main": { "code": 65307, "label": ";" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65281, "label": "!", "popup": {
|
||||
"main": { "code": 33, "label": "!" },
|
||||
"relevant": [
|
||||
{ "code": 161, "label": "¡" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 33, "label": "!", "popup": {
|
||||
"main": { "code": 65281, "label": "!" },
|
||||
"relevant": [
|
||||
{ "code": 161, "label": "¡" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$": "char_width_selector",
|
||||
"full": { "code": 65311, "label": "?", "popup": {
|
||||
"main": { "code": 63, "label": "?" },
|
||||
"relevant": [
|
||||
{ "code": 191, "label": "¿" },
|
||||
{ "code": 8253, "label": "‽" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 63, "label": "?", "popup": {
|
||||
"main": { "code": 65311, "label": "?" },
|
||||
"relevant": [
|
||||
{ "code": 191, "label": "¿" },
|
||||
{ "code": 8253, "label": "‽" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
55
app/src/main/assets/ime/text/symbols/mod/cjk.json
Normal file
55
app/src/main/assets/ime/text/symbols/mod/cjk.json
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"type": "symbols/mod",
|
||||
"name": "cjk",
|
||||
"label": "CJK",
|
||||
"authors": [ "waelwindows" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": -203, "label": "view_symbols2", "type": "system_gui" },
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -5, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -201, "label": "view_characters", "type": "system_gui" },
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 12289, "label": "、", "popup": {
|
||||
"main": { "code": 44, "label": "," }
|
||||
}
|
||||
},
|
||||
"half": { "code": 65380, "label": "、", "popup": {
|
||||
"main": { "code": 44, "label": "," }
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "code": -205, "label": "view_numeric_advanced", "type": "system_gui" },
|
||||
{ "code": 12288, "label": "空白" },
|
||||
{ "code": -9701, "label": "char_width_switcher", "type": "system_gui", "popup": {
|
||||
"relevant": [
|
||||
{ "code": -9702, "label": "char_width_full", "type": "system_gui" },
|
||||
{ "code": -9703, "label": "char_width_half", "type": "system_gui" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 12290, "label": "。", "popup": {
|
||||
"main": { "code": 8230, "label": "…" },
|
||||
"relevant": [
|
||||
{ "code": 12539, "label": "・" },
|
||||
{ "code": 46, "label": "." }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 65377, "label": "。", "popup": {
|
||||
"main": { "code": 8230, "label": "…" },
|
||||
"relevant": [
|
||||
{ "code": 65381, "label": "・" },
|
||||
{ "code": 46, "label": "." }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
}
|
||||
22
app/src/main/assets/ime/text/symbols/mod/neo2.json
Normal file
22
app/src/main/assets/ime/text/symbols/mod/neo2.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"type": "symbols/mod",
|
||||
"name": "neo2",
|
||||
"label": "Neo2",
|
||||
"authors": [ "ostrya" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": -203, "label": "view_symbols2", "type": "system_gui" },
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -5, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -201, "label": "view_characters", "type": "system_gui" },
|
||||
{ "code": -205, "label": "view_numeric_advanced", "type": "system_gui" },
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "code": 34, "label": "\"" },
|
||||
{ "code": 39, "label": "'" },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
}
|
||||
46
app/src/main/assets/ime/text/symbols/neo2.json
Normal file
46
app/src/main/assets/ime/text/symbols/neo2.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"type": "symbols",
|
||||
"name": "neo2",
|
||||
"label": "Neo2",
|
||||
"authors": [ "ostrya" ],
|
||||
"direction": "ltr",
|
||||
"modifier": "neo2",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 8230, "label": "…" },
|
||||
{ "code": 95, "label": "_" },
|
||||
{ "code": 91, "label": "[" },
|
||||
{ "code": 93, "label": "]" },
|
||||
{ "code": 94, "label": "^" },
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 60, "label": "<" },
|
||||
{ "code": 62, "label": ">" },
|
||||
{ "code": 61, "label": "=" },
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 383, "label": "ſ" }
|
||||
],
|
||||
[
|
||||
{ "code": 92, "label": "\\" },
|
||||
{ "code": 47, "label": "/" },
|
||||
{ "code": 123, "label": "{" },
|
||||
{ "code": 125, "label": "}" },
|
||||
{ "code": 42, "label": "*" },
|
||||
{ "code": 63, "label": "?" },
|
||||
{ "code": 40, "label": "(" },
|
||||
{ "code": 41, "label": ")" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 64, "label": "@" }
|
||||
],
|
||||
[
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 36, "label": "$" },
|
||||
{ "code": 124, "label": "|" },
|
||||
{ "code": 126, "label": "~" },
|
||||
{ "code": 96, "label": "`" },
|
||||
{ "code": 43, "label": "+" },
|
||||
{ "code": 37, "label": "%" },
|
||||
{ "code": 59, "label": ";" }
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
{
|
||||
"type": "symbols",
|
||||
"name": "western-additional-symbols",
|
||||
"label": "Western (Additional symbols)",
|
||||
"authors": [ "patrickgold" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{"code": 37, "label": "%"},
|
||||
{"code": 92, "label": "\\"},
|
||||
{"code":124, "label": "|"},
|
||||
{"code": 61, "label": "="},
|
||||
{"code": 91, "label": "["},
|
||||
{"code": 93, "label": "]"},
|
||||
{"code": 60, "label": "<"},
|
||||
{"code": 63, "label": ">"},
|
||||
{"code": 123, "label": "{"},
|
||||
{"code": 125, "label": "}"}
|
||||
],
|
||||
[
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 35, "label": "#", "popup": {
|
||||
"main": { "code": 8470, "label": "№" }
|
||||
} },
|
||||
{ "code": -801, "label": "currency_slot_1", "popup": {
|
||||
"main": { "code": -802, "label": "currency_slot_2" },
|
||||
"relevant": [
|
||||
{ "code": -806, "label": "currency_slot_6" },
|
||||
{ "code": -803, "label": "currency_slot_3" },
|
||||
{ "code": -804, "label": "currency_slot_4" },
|
||||
{ "code": -805, "label": "currency_slot_5" }
|
||||
]
|
||||
} },
|
||||
{ "code": 37, "label": "%", "popup": {
|
||||
"main": { "code": 8240, "label": "‰" },
|
||||
"relevant": [
|
||||
{ "code": 8453, "label": "℅" }
|
||||
]
|
||||
} },
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 45, "label": "-", "popup": {
|
||||
"main": { "code": 95, "label": "_" },
|
||||
"relevant": [
|
||||
{ "code": 8212, "label": "—" },
|
||||
{ "code": 8211, "label": "–" },
|
||||
{ "code": 183, "label": "·" }
|
||||
]
|
||||
} },
|
||||
{ "code": 43, "label": "+", "popup": {
|
||||
"main": { "code": 177, "label": "±" }
|
||||
} },
|
||||
{ "code": 40, "label": "(", "popup": {
|
||||
"main": { "code": 60, "label": "<" },
|
||||
"relevant": [
|
||||
{ "code": 91, "label": "[" },
|
||||
{ "code": 123, "label": "{" }
|
||||
]
|
||||
} },
|
||||
{ "code": 41, "label": ")", "popup": {
|
||||
"main": { "code": 62, "label": ">" },
|
||||
"relevant": [
|
||||
{ "code": 93, "label": "]" },
|
||||
{ "code": 125, "label": "}" }
|
||||
]
|
||||
} },
|
||||
{ "code": 47, "label": "/" }
|
||||
],
|
||||
[
|
||||
{ "code": 42, "label": "*", "popup": {
|
||||
"main": { "code": 8224, "label": "†" },
|
||||
"relevant": [
|
||||
{ "code": 9733, "label": "★" },
|
||||
{ "code": 8225, "label": "‡" }
|
||||
]
|
||||
} },
|
||||
{ "code": 34, "label": "\"", "popup": {
|
||||
"main": { "code": 8221, "label": "”" },
|
||||
"relevant": [
|
||||
{ "code": 8222, "label": "„" },
|
||||
{ "code": 8220, "label": "“" },
|
||||
{ "code": 171, "label": "«" },
|
||||
{ "code": 187, "label": "»" }
|
||||
]
|
||||
} },
|
||||
{ "code": 39, "label": "'", "popup": {
|
||||
"main": { "code": 8217, "label": "’" },
|
||||
"relevant": [
|
||||
{ "code": 8218, "label": "‚" },
|
||||
{ "code": 8216, "label": "‘" },
|
||||
{ "code": 8249, "label": "‹" },
|
||||
{ "code": 8250, "label": "›" }
|
||||
]
|
||||
} },
|
||||
{ "code": 58, "label": ":", "popup": {
|
||||
"main": { "code": 8942, "label": "⋮" }
|
||||
} },
|
||||
{ "code": 59, "label": ";" },
|
||||
{ "code": 33, "label": "!", "popup": {
|
||||
"main": { "code": 161, "label": "¡" }
|
||||
} },
|
||||
{ "code": 63, "label": "?", "popup": {
|
||||
"main": { "code": 191, "label": "¿" },
|
||||
"relevant": [
|
||||
{ "code": 8253, "label": "‽" }
|
||||
]
|
||||
} }
|
||||
]
|
||||
]
|
||||
}
|
||||
225
app/src/main/assets/ime/text/symbols2/cjk.json
Normal file
225
app/src/main/assets/ime/text/symbols2/cjk.json
Normal file
@@ -0,0 +1,225 @@
|
||||
{
|
||||
"type": "symbols2",
|
||||
"name": "cjk",
|
||||
"label": "CJK",
|
||||
"authors": [ "waelwindows" ],
|
||||
"direction": "ltr",
|
||||
"modifier": "cjk",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 12316, "label": "〜", "popup": {
|
||||
"main": { "code": 126, "label": "~" }
|
||||
}
|
||||
},
|
||||
"half": { "code": 126, "label": "~", "popup": {
|
||||
"main": { "code": 12316, "label": "〜" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65344, "label": "`", "popup": {
|
||||
"main": { "code": 96, "label": "`" }
|
||||
}
|
||||
},
|
||||
"half": { "code": 96, "label": "`", "popup": {
|
||||
"main": { "code": 65344, "label": "`" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65372, "label": "|", "popup": {
|
||||
"main": { "code": 124, "label": "|" }
|
||||
}
|
||||
},
|
||||
"half": { "code": 124, "label": "|", "popup": {
|
||||
"main": { "code": 65372, "label": "|" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full":
|
||||
{ "code": 12539, "label": "・", "popup": {
|
||||
"main": { "code": 9834, "label": "♪" },
|
||||
"relevant": [
|
||||
{ "code": 8226, "label": "•" },
|
||||
{ "code": 9827, "label": "♣" },
|
||||
{ "code": 9824, "label": "♠" },
|
||||
{ "code": 9829, "label": "♥" },
|
||||
{ "code": 9830, "label": "♦" }
|
||||
]
|
||||
} },
|
||||
"half":
|
||||
{ "code": 8226, "label": "•", "popup": {
|
||||
"main": { "code": 9834, "label": "♪" },
|
||||
"relevant": [
|
||||
{ "code": 12539, "label": "・" },
|
||||
{ "code": 9827, "label": "♣" },
|
||||
{ "code": 9824, "label": "♠" },
|
||||
{ "code": 9829, "label": "♥" },
|
||||
{ "code": 9830, "label": "♦" }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "code": 8730, "label": "√" },
|
||||
{ "code": 960, "label": "π", "popup": {
|
||||
"main": { "code": 928, "label": "Π" },
|
||||
"relevant": [
|
||||
{ "code": 969, "label": "ω" },
|
||||
{ "code": 945, "label": "α" },
|
||||
{ "code": 946, "label": "β" },
|
||||
{ "code": 937, "label": "Ω" },
|
||||
{ "code": 956, "label": "μ" }
|
||||
]
|
||||
} },
|
||||
{ "code": 247, "label": "÷" },
|
||||
{ "code": 215, "label": "×" },
|
||||
{ "code": 182, "label": "¶" },
|
||||
{ "code": 8710, "label": "∆" }
|
||||
],
|
||||
[
|
||||
{ "code": -805, "label": "currency_slot_5" },
|
||||
{ "code": -804, "label": "currency_slot_4" },
|
||||
{ "code": -803, "label": "currency_slot_3" },
|
||||
{ "code": -802, "label": "currency_slot_2" },
|
||||
{ "code": 94, "label": "^", "popup": {
|
||||
"main": { "code": 8593, "label": "↑" },
|
||||
"relevant": [
|
||||
{ "code": 8592, "label": "←" },
|
||||
{ "code": 8595, "label": "↓" },
|
||||
{ "code": 8594, "label": "→" }
|
||||
]
|
||||
} },
|
||||
{ "code": 176, "label": "°", "popup": {
|
||||
"main": { "code": 8242, "label": "′" },
|
||||
"relevant": [
|
||||
{ "code": 8243, "label": "″" }
|
||||
]
|
||||
} },
|
||||
{ "$": "char_width_selector",
|
||||
"full":
|
||||
{ "code": 65309, "label": "=", "popup": {
|
||||
"main": { "code": 8800, "label": "≠" },
|
||||
"relevant": [
|
||||
{ "code": 61, "label": "=" },
|
||||
{ "code": 8734, "label": "∞" },
|
||||
{ "code": 8776, "label": "≈" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half":
|
||||
{ "code": 61, "label": "=", "popup": {
|
||||
"main": { "code": 8800, "label": "≠" },
|
||||
"relevant": [
|
||||
{ "code": 61, "label": "=" },
|
||||
{ "code": 8734, "label": "∞" },
|
||||
{ "code": 8776, "label": "≈" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65371, "label": "{", "popup": {
|
||||
"main": { "code": 65288, "label": "(" },
|
||||
"relevant": [
|
||||
{ "code": 123, "label": "{" },
|
||||
{ "code": 12308, "label": "〔" },
|
||||
{ "code": 12312, "label": "〘" },
|
||||
{ "code": 65375, "label": "⦅" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 123, "label": "{", "popup": {
|
||||
"main": { "code": 40, "label": "(" },
|
||||
"relevant": [
|
||||
{ "code": 65371, "label": "{" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65373, "label": "}", "popup": {
|
||||
"main": { "code": 65289, "label": ")" },
|
||||
"relevant": [
|
||||
{ "code": 125, "label": "}" },
|
||||
{ "code": 12309, "label": "〕" },
|
||||
{ "code": 12313, "label": "〙" },
|
||||
{ "code": 65376, "label": "⦆" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 125, "label": "}", "popup": {
|
||||
"main": { "code": 41, "label": ")" },
|
||||
"relevant": [
|
||||
{ "code": 65373, "label": "}" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65340, "label": "\", "popup": {
|
||||
"main": { "code": 92, "label": "\\" }
|
||||
}
|
||||
},
|
||||
"half": { "code": 92, "label": "\\", "popup": {
|
||||
"main": { "code": 65340, "label": "\" }
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "code": 12292, "label": "〄" },
|
||||
{ "code": 12293, "label": "々" },
|
||||
{ "code": 12294, "label": "〆" },
|
||||
{ "code": 12295, "label": "〇" },
|
||||
{ "$": "kana_selector",
|
||||
"hira": { "code": 12445, "label": "ゝ", "popup": {
|
||||
"main": { "code": 12446, "label": "ゞ" },
|
||||
"relevant": [
|
||||
{ "code": 12541, "label": "ヽ" },
|
||||
{ "code": 12542, "label": "ヾ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"kata": { "code": 12541, "label": "ヽ", "popup": {
|
||||
"main": { "code": 12542, "label": "ヾ" },
|
||||
"relevant": [
|
||||
{ "code": 12445, "label": "ゝ" },
|
||||
{ "code": 12446, "label": "ゞ" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65339, "label": "[", "popup": {
|
||||
"main": { "code": 91, "label": "[" },
|
||||
"relevant": [
|
||||
{ "code": 12314, "label": "〚" },
|
||||
{ "code": 12304, "label": "【" },
|
||||
{ "code": 12310, "label": "〖" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 91, "label": "[", "popup": {
|
||||
"main": { "code": 65339, "label": "[" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "char_width_selector",
|
||||
"full": { "code": 65341, "label": "]", "popup": {
|
||||
"main": { "code": 93, "label": "]" },
|
||||
"relevant": [
|
||||
{ "code": 12315, "label": "〛" },
|
||||
{ "code": 12305, "label": "】" },
|
||||
{ "code": 12311, "label": "〗" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"half": { "code": 93, "label": "]", "popup": {
|
||||
"main": { "code": 65341, "label": "]" }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
45
app/src/main/assets/ime/text/symbols2/mod/cjk.json
Normal file
45
app/src/main/assets/ime/text/symbols2/mod/cjk.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"type": "symbols2/mod",
|
||||
"name": "cjk",
|
||||
"label": "CJK",
|
||||
"authors": [ "waelwindows" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -5, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -201, "label": "view_characters", "type": "system_gui" },
|
||||
{ "code": 12296, "label": "〈", "popup": {
|
||||
"main": { "code": 12298, "label": "《" },
|
||||
"relevant": [
|
||||
{ "code": 8804, "label": "≤" },
|
||||
{ "code": 8249, "label": "‹" },
|
||||
{ "code": 10216, "label": "⟨" },
|
||||
{ "code": 65308, "label": "<" }
|
||||
]
|
||||
} },
|
||||
{ "code": -205, "label": "view_numeric_advanced", "type": "system_gui" },
|
||||
{ "code": 12288, "label": "空白" },
|
||||
{ "code": -9701, "label": "char_width_switcher", "type": "system_gui", "popup": {
|
||||
"relevant": [
|
||||
{ "code": -9702, "label": "char_width_full", "type": "system_gui" },
|
||||
{ "code": -9703, "label": "char_width_half", "type": "system_gui" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ "code": 12297, "label": "〉", "popup": {
|
||||
"main": { "code": 12299, "label": "》" },
|
||||
"relevant": [
|
||||
{ "code": 62, "label": ">" },
|
||||
{ "code": 8805, "label": "≥" },
|
||||
{ "code": 10217, "label": "⟩" },
|
||||
{ "code": 65310, "label": ">" }
|
||||
]
|
||||
} },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
201
app/src/main/assets/license/project_license.txt
Normal file
201
app/src/main/assets/license/project_license.txt
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2020 Patrick Goldinger
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
48
app/src/main/cpp/CMakeLists.txt
Normal file
48
app/src/main/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
# For more information about using CMake with Android Studio, read the
|
||||
# documentation: https://d.android.com/studio/projects/add-native-code.html
|
||||
|
||||
cmake_minimum_required(VERSION 3.10.2)
|
||||
|
||||
project("florisboard")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
include_directories(.)
|
||||
|
||||
### ICU4C ###
|
||||
include_directories(../icu4c/prebuilt/include)
|
||||
set(JNI_LIBS ${CMAKE_SOURCE_DIR}/../icu4c/prebuilt/jniLibs/${ANDROID_ABI})
|
||||
add_library(ICU::data STATIC IMPORTED)
|
||||
set_property(TARGET ICU::data PROPERTY IMPORTED_LOCATION "${JNI_LIBS}/libicudata.a")
|
||||
add_library(ICU::uc STATIC IMPORTED)
|
||||
set_property(TARGET ICU::uc PROPERTY IMPORTED_LOCATION "${JNI_LIBS}/libicuuc.a")
|
||||
|
||||
### FlorisBoard ###
|
||||
add_subdirectory(nuspell)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(ime/nlp)
|
||||
add_subdirectory(ime/spelling)
|
||||
|
||||
add_library(
|
||||
florisboard-native
|
||||
SHARED
|
||||
dev_patrickgold_florisboard_FlorisApplication.cpp
|
||||
dev_patrickgold_florisboard_ime_nlp_SuggestionList.cpp
|
||||
dev_patrickgold_florisboard_ime_spelling_SpellingDict.cpp
|
||||
)
|
||||
|
||||
target_compile_options(florisboard-native PRIVATE -ffunction-sections -fdata-sections -fexceptions)
|
||||
target_link_libraries(
|
||||
# Destination
|
||||
florisboard-native
|
||||
|
||||
# Sources
|
||||
android
|
||||
log
|
||||
ICU::uc
|
||||
ICU::data
|
||||
Nuspell::nuspell
|
||||
utils
|
||||
ime-nlp
|
||||
ime-spelling
|
||||
)
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <jni.h>
|
||||
#include <unicode/udata.h>
|
||||
#include "utils/jni_utils.h"
|
||||
|
||||
#pragma ide diagnostic ignored "UnusedLocalVariable"
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_dev_patrickgold_florisboard_FlorisApplication_00024Companion_nativeInitICUData(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jobject path) {
|
||||
auto path_str = utils::j2std_string(env, path);
|
||||
std::ifstream in_file(path_str, std::ios::in | std::ios::binary);
|
||||
if (!in_file) {
|
||||
return U_FILE_ACCESS_ERROR;
|
||||
}
|
||||
in_file.seekg(0, std::ios::end);
|
||||
size_t size = in_file.tellg();
|
||||
if (size <= 0) {
|
||||
return U_FILE_ACCESS_ERROR;
|
||||
}
|
||||
in_file.seekg(0, std::ios::beg);
|
||||
char *icu_data = new char[size + 1];
|
||||
in_file.read(icu_data, size);
|
||||
if (!in_file) {
|
||||
in_file.close();
|
||||
return U_FILE_ACCESS_ERROR;
|
||||
}
|
||||
icu_data[size] = 0;
|
||||
in_file.close();
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
udata_setCommonData(reinterpret_cast<void *>(icu_data), &status);
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include "ime/nlp/suggestion_list.h"
|
||||
|
||||
#pragma ide diagnostic ignored "UnusedLocalVariable"
|
||||
|
||||
using namespace ime::nlp;
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeInitialize(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jint max_size) {
|
||||
auto *suggestionList = new SuggestionList(max_size);
|
||||
return reinterpret_cast<jlong>(suggestionList);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeDispose(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
suggestionList->clear();
|
||||
delete suggestionList;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeAdd(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr,
|
||||
jstring word,
|
||||
jint freq) {
|
||||
const char *cWord = env->GetStringUTFChars(word, nullptr);
|
||||
word_t stdWord = word_t(cWord);
|
||||
env->ReleaseStringUTFChars(word, cWord);
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
return suggestionList->add(std::move(stdWord), freq);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeClear(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
suggestionList->clear();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeContains(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr,
|
||||
jstring element) {
|
||||
const char *cWord = env->GetStringUTFChars(element, nullptr);
|
||||
const word_t stdWord = word_t(cWord);
|
||||
env->ReleaseStringUTFChars(element, cWord);
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
return suggestionList->containsWord(stdWord);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeGetOrNull(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr,
|
||||
jint index) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
auto weightedToken = suggestionList->get(index);
|
||||
if (weightedToken == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
return env->NewStringUTF(weightedToken->data.c_str());
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeSize(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
return suggestionList->size();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeGetIsPrimaryTokenAutoInsert(
|
||||
JNIEnv *env, jobject thiz, jlong native_ptr) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
return suggestionList->isPrimaryTokenAutoInsert;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeSetIsPrimaryTokenAutoInsert(
|
||||
JNIEnv *env, jobject thiz, jlong native_ptr, jboolean v) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
suggestionList->isPrimaryTokenAutoInsert = v;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include <algorithm>
|
||||
#include "ime/spelling/spellingdict.h"
|
||||
#include "utils/jni_utils.h"
|
||||
|
||||
#pragma ide diagnostic ignored "UnusedLocalVariable"
|
||||
|
||||
using namespace ime::spellcheck;
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_spelling_SpellingDict_00024Companion_nativeInitialize(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jobject base_path) {
|
||||
auto strBasePath = utils::j2std_string(env, base_path);
|
||||
|
||||
auto *spellingDict = SpellingDict::load(strBasePath);
|
||||
|
||||
if (spellingDict == nullptr) {
|
||||
return 0L;
|
||||
} else {
|
||||
return reinterpret_cast<jlong>(spellingDict);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_spelling_SpellingDict_00024Companion_nativeDispose(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr) {
|
||||
auto spellingDict = reinterpret_cast<SpellingDict *>(native_ptr);
|
||||
|
||||
delete spellingDict;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_spelling_SpellingDict_00024Companion_nativeSpell(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr,
|
||||
jobject word) {
|
||||
auto strWord = utils::j2std_string(env, word);
|
||||
|
||||
auto spellingDict = reinterpret_cast<SpellingDict *>(native_ptr);
|
||||
auto result = spellingDict->spell(strWord);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_spelling_SpellingDict_00024Companion_nativeSuggest(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr,
|
||||
jobject word,
|
||||
jint limit) {
|
||||
auto strWord = utils::j2std_string(env, word);
|
||||
|
||||
auto spellingDict = reinterpret_cast<SpellingDict *>(native_ptr);
|
||||
auto result = spellingDict->suggest(strWord);
|
||||
auto retSize = std::min(result.size(), (size_t)std::max(0, limit));
|
||||
|
||||
jclass jByteArrayClass = env->FindClass("java/nio/ByteBuffer");
|
||||
jobjectArray jSuggestions = env->NewObjectArray(retSize, jByteArrayClass, nullptr);
|
||||
for (int n = 0; n < retSize; n++) {
|
||||
env->SetObjectArrayElement(jSuggestions, n, utils::std2j_string(env, result[n]));
|
||||
}
|
||||
|
||||
return jSuggestions;
|
||||
}
|
||||
13
app/src/main/cpp/ime/nlp/CMakeLists.txt
Normal file
13
app/src/main/cpp/ime/nlp/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
add_library(
|
||||
# Name
|
||||
ime-nlp
|
||||
|
||||
# Headers
|
||||
nlp.h
|
||||
token.h
|
||||
suggestion_list.h
|
||||
|
||||
# Sources
|
||||
token.cpp
|
||||
suggestion_list.cpp
|
||||
)
|
||||
32
app/src/main/cpp/ime/nlp/nlp.h
Normal file
32
app/src/main/cpp/ime/nlp/nlp.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLORISBOARD_NLP_H
|
||||
#define FLORISBOARD_NLP_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ime::nlp {
|
||||
|
||||
typedef std::string word_t;
|
||||
typedef uint16_t freq_t;
|
||||
|
||||
static const freq_t FREQ_VALUE_MASK = 0xFF;
|
||||
static const freq_t FREQ_POSSIBLY_OFFENSIVE = 0x01;
|
||||
|
||||
} // namespace ime::nlp
|
||||
|
||||
#endif // FLORISBOARD_NLP_H
|
||||
98
app/src/main/cpp/ime/nlp/suggestion_list.cpp
Normal file
98
app/src/main/cpp/ime/nlp/suggestion_list.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "suggestion_list.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace ime::nlp;
|
||||
|
||||
SuggestionList::SuggestionList(size_t _maxSize) :
|
||||
maxSize(_maxSize), internalSize(0), tokens(_maxSize), isPrimaryTokenAutoInsert(false)
|
||||
{ }
|
||||
|
||||
SuggestionList::~SuggestionList() = default;
|
||||
|
||||
bool SuggestionList::add(word_t &&word, freq_t &&freq) {
|
||||
auto entryIndex = indexOfWord(word);
|
||||
if (entryIndex.has_value()) {
|
||||
// Word exists already
|
||||
auto entry = tokens[entryIndex.value()];
|
||||
if (entry.freq < freq) {
|
||||
// Need to update freq
|
||||
entry.freq = freq;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (internalSize < maxSize) {
|
||||
tokens[internalSize++] = WeightedToken(std::move(word), freq);
|
||||
} else {
|
||||
auto last = tokens[internalSize - 1];
|
||||
if (last.freq < freq) {
|
||||
tokens[internalSize - 1] = WeightedToken(std::move(word), freq);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(tokens.begin(), tokens.begin() + internalSize, std::greater<>());
|
||||
return true;
|
||||
}
|
||||
|
||||
void SuggestionList::clear() {
|
||||
internalSize = 0;
|
||||
isPrimaryTokenAutoInsert = false;
|
||||
}
|
||||
|
||||
bool SuggestionList::contains(const WeightedToken &element) const {
|
||||
return indexOf(element).has_value();
|
||||
}
|
||||
|
||||
bool SuggestionList::containsWord(const word_t &word) const {
|
||||
return indexOfWord(word).has_value();
|
||||
}
|
||||
|
||||
const WeightedToken *SuggestionList::get(size_t index) const {
|
||||
if (index < 0 || index >= internalSize) return nullptr;
|
||||
return &tokens[index];
|
||||
}
|
||||
|
||||
std::optional<size_t> SuggestionList::indexOf(const WeightedToken &element) const {
|
||||
for (size_t n = 0; n < internalSize; n++) {
|
||||
if (element == tokens[n]) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<size_t> SuggestionList::indexOfWord(const word_t &word) const {
|
||||
for (size_t n = 0; n < internalSize; n++) {
|
||||
if (word == tokens[n].data) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool SuggestionList::isEmpty() const {
|
||||
return internalSize == 0;
|
||||
}
|
||||
|
||||
size_t SuggestionList::size() const {
|
||||
return internalSize;
|
||||
}
|
||||
51
app/src/main/cpp/ime/nlp/suggestion_list.h
Normal file
51
app/src/main/cpp/ime/nlp/suggestion_list.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLORISBOARD_SUGGESTION_LIST_H
|
||||
#define FLORISBOARD_SUGGESTION_LIST_H
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include "token.h"
|
||||
|
||||
namespace ime::nlp {
|
||||
|
||||
class SuggestionList {
|
||||
public:
|
||||
SuggestionList(size_t _maxSize);
|
||||
~SuggestionList();
|
||||
|
||||
bool add(word_t &&word, freq_t &&freq);
|
||||
void clear();
|
||||
bool contains(const WeightedToken &element) const;
|
||||
bool containsWord(const word_t &word) const;
|
||||
const WeightedToken *get(size_t index) const;
|
||||
std::optional<size_t> indexOf(const WeightedToken &element) const;
|
||||
std::optional<size_t> indexOfWord(const word_t &word) const;
|
||||
bool isEmpty() const;
|
||||
size_t size() const;
|
||||
|
||||
bool isPrimaryTokenAutoInsert;
|
||||
|
||||
private:
|
||||
std::vector<WeightedToken> tokens;
|
||||
size_t internalSize;
|
||||
size_t maxSize;
|
||||
};
|
||||
|
||||
} // namespace ime::nlp
|
||||
|
||||
#endif // FLORISBOARD_SUGGESTION_LIST_H
|
||||
61
app/src/main/cpp/ime/nlp/token.cpp
Normal file
61
app/src/main/cpp/ime/nlp/token.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "token.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace ime::nlp {
|
||||
|
||||
Token::Token() : data() {}
|
||||
Token::Token(word_t &&_data) : data(std::move(_data)) {}
|
||||
|
||||
bool operator==(const Token &t1, const Token &t2) {
|
||||
return t1.data == t2.data;
|
||||
}
|
||||
|
||||
bool operator!=(const Token &t1, const Token &t2) {
|
||||
return !(t1 == t2);
|
||||
}
|
||||
|
||||
WeightedToken::WeightedToken() : Token(), freq(0) {}
|
||||
WeightedToken::WeightedToken(word_t &&_data, freq_t _freq) : Token(std::move(_data)), freq(_freq) {}
|
||||
|
||||
bool operator==(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return t1.data == t2.data && t1.freq == t2.freq;
|
||||
}
|
||||
|
||||
bool operator!=(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return !(t1 == t2);
|
||||
}
|
||||
|
||||
bool operator<(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return t1.freq < t2.freq;
|
||||
}
|
||||
|
||||
bool operator<=(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return t1.freq <= t2.freq;
|
||||
}
|
||||
|
||||
bool operator>(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return t1.freq > t2.freq;
|
||||
}
|
||||
|
||||
bool operator>=(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return t1.freq >= t2.freq;
|
||||
}
|
||||
|
||||
} // namespace ime::nlp
|
||||
51
app/src/main/cpp/ime/nlp/token.h
Normal file
51
app/src/main/cpp/ime/nlp/token.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLORISBOARD_TOKEN_H
|
||||
#define FLORISBOARD_TOKEN_H
|
||||
|
||||
#include "nlp.h"
|
||||
#include <string>
|
||||
|
||||
namespace ime::nlp {
|
||||
|
||||
class Token {
|
||||
public:
|
||||
word_t data;
|
||||
Token();
|
||||
Token(word_t &&_data);
|
||||
|
||||
friend bool operator==(const Token &t1, const Token &t2);
|
||||
friend bool operator!=(const Token &t1, const Token &t2);
|
||||
};
|
||||
|
||||
class WeightedToken : public Token {
|
||||
public:
|
||||
freq_t freq;
|
||||
WeightedToken();
|
||||
WeightedToken(word_t &&_data, freq_t _freq);
|
||||
|
||||
friend bool operator==(const WeightedToken &t1, const WeightedToken &t2);
|
||||
friend bool operator!=(const WeightedToken &t1, const WeightedToken &t2);
|
||||
friend bool operator<(const WeightedToken &t1, const WeightedToken &t2);
|
||||
friend bool operator<=(const WeightedToken &t1, const WeightedToken &t2);
|
||||
friend bool operator>(const WeightedToken &t1, const WeightedToken &t2);
|
||||
friend bool operator>=(const WeightedToken &t1, const WeightedToken &t2);
|
||||
};
|
||||
|
||||
} // namespace ime::nlp
|
||||
|
||||
#endif // FLORISBOARD_TOKEN_H
|
||||
10
app/src/main/cpp/ime/spelling/CMakeLists.txt
Normal file
10
app/src/main/cpp/ime/spelling/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
add_library(
|
||||
# Name
|
||||
ime-spelling
|
||||
|
||||
# Headers
|
||||
spellingdict.h
|
||||
|
||||
# Sources
|
||||
spellingdict.cpp
|
||||
)
|
||||
51
app/src/main/cpp/ime/spelling/spellingdict.cpp
Normal file
51
app/src/main/cpp/ime/spelling/spellingdict.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "spellingdict.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
using namespace ime::spellcheck;
|
||||
|
||||
SpellingDict::SpellingDict(const nuspell::Dictionary& dict) : dictionary(std::make_unique<nuspell::Dictionary>(dict))
|
||||
{ }
|
||||
|
||||
SpellingDict::~SpellingDict() = default;
|
||||
|
||||
SpellingDict* SpellingDict::load(const std::string &basePath) {
|
||||
utils::start_stdout_stderr_logger("spell-floris");
|
||||
try {
|
||||
auto temp = nuspell::Dictionary::load_from_path(basePath);
|
||||
auto spellingDict = new SpellingDict(temp);
|
||||
return spellingDict;
|
||||
} catch (const nuspell::Dictionary_Loading_Error& e) {
|
||||
utils::log_error("SpellingDict.load()", e.what());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
utils::log_error("SpellingDict.load()", "An unknown error occurred!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool SpellingDict::spell(const std::string& word) {
|
||||
bool result = dictionary->spell(word);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> SpellingDict::suggest(const std::string &word) {
|
||||
auto result = std::vector<std::string>();
|
||||
dictionary->suggest(word, result);
|
||||
return result;
|
||||
}
|
||||
42
app/src/main/cpp/ime/spelling/spellingdict.h
Normal file
42
app/src/main/cpp/ime/spelling/spellingdict.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLORISBOARD_SPELLINGDICT_H
|
||||
#define FLORISBOARD_SPELLINGDICT_H
|
||||
|
||||
#include "nuspell/dictionary.hxx"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ime::spellcheck {
|
||||
|
||||
class SpellingDict {
|
||||
public:
|
||||
SpellingDict(const nuspell::Dictionary& dict);
|
||||
~SpellingDict();
|
||||
|
||||
static SpellingDict* load(const std::string& basePath);
|
||||
|
||||
bool spell(const std::string& word);
|
||||
std::vector<std::string> suggest(const std::string& word);
|
||||
|
||||
private:
|
||||
std::unique_ptr<nuspell::Dictionary> dictionary;
|
||||
};
|
||||
|
||||
} // namespace ime::spellcheck
|
||||
|
||||
#endif // FLORISBOARD_SPELLINGDICT_H
|
||||
10
app/src/main/cpp/nuspell/CMakeLists.txt
Normal file
10
app/src/main/cpp/nuspell/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
add_library(nuspell
|
||||
aff_data.cxx aff_data.hxx
|
||||
checker.cxx checker.hxx
|
||||
suggester.cxx suggester.hxx
|
||||
dictionary.cxx dictionary.hxx
|
||||
unicode.hxx
|
||||
utils.cxx utils.hxx
|
||||
structures.hxx)
|
||||
|
||||
add_library(Nuspell::nuspell ALIAS nuspell)
|
||||
165
app/src/main/cpp/nuspell/LICENSE.txt
Normal file
165
app/src/main/cpp/nuspell/LICENSE.txt
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
1064
app/src/main/cpp/nuspell/aff_data.cxx
Normal file
1064
app/src/main/cpp/nuspell/aff_data.cxx
Normal file
File diff suppressed because it is too large
Load Diff
173
app/src/main/cpp/nuspell/aff_data.hxx
Normal file
173
app/src/main/cpp/nuspell/aff_data.hxx
Normal file
@@ -0,0 +1,173 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NUSPELL_AFF_DATA_HXX
|
||||
#define NUSPELL_AFF_DATA_HXX
|
||||
|
||||
#include "nuspell_export.h"
|
||||
#include "structures.hxx"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <unicode/locid.h>
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
class Encoding {
|
||||
std::string name;
|
||||
|
||||
NUSPELL_EXPORT auto normalize_name() -> void;
|
||||
|
||||
public:
|
||||
enum Enc_Type { SINGLEBYTE = false, UTF8 = true };
|
||||
|
||||
Encoding() = default;
|
||||
explicit Encoding(const std::string& e) : name(e) { normalize_name(); }
|
||||
explicit Encoding(std::string&& e) : name(move(e)) { normalize_name(); }
|
||||
explicit Encoding(const char* e) : name(e) { normalize_name(); }
|
||||
auto& operator=(const std::string& e)
|
||||
{
|
||||
name = e;
|
||||
normalize_name();
|
||||
return *this;
|
||||
}
|
||||
auto& operator=(std::string&& e)
|
||||
{
|
||||
name = move(e);
|
||||
normalize_name();
|
||||
return *this;
|
||||
}
|
||||
auto& operator=(const char* e)
|
||||
{
|
||||
name = e;
|
||||
normalize_name();
|
||||
return *this;
|
||||
}
|
||||
auto empty() const { return name.empty(); }
|
||||
auto& value() const { return name; }
|
||||
auto is_utf8() const { return name == "UTF-8"; }
|
||||
auto value_or_default() const -> std::string
|
||||
{
|
||||
if (name.empty())
|
||||
return "ISO8859-1";
|
||||
else
|
||||
return name;
|
||||
}
|
||||
operator Enc_Type() const { return is_utf8() ? UTF8 : SINGLEBYTE; }
|
||||
};
|
||||
|
||||
enum class Flag_Type { SINGLE_CHAR, DOUBLE_CHAR, NUMBER, UTF8 };
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Map between words and word_flags.
|
||||
*
|
||||
* Flags are stored as part of the container. Maybe for the future flags should
|
||||
* be stored elsewhere (flag aliases) and this should store pointers.
|
||||
*
|
||||
* Does not store morphological data as is low priority feature and is out of
|
||||
* scope.
|
||||
*/
|
||||
using Word_List = Hash_Multimap<std::string, Flag_Set>;
|
||||
|
||||
struct Aff_Data {
|
||||
static constexpr auto HIDDEN_HOMONYM_FLAG = char16_t(-1);
|
||||
static constexpr auto MAX_SUGGESTIONS = size_t(16);
|
||||
|
||||
// spell checking options
|
||||
Word_List words;
|
||||
Prefix_Table prefixes;
|
||||
Suffix_Table suffixes;
|
||||
|
||||
bool complex_prefixes;
|
||||
bool fullstrip;
|
||||
bool checksharps;
|
||||
bool forbid_warn;
|
||||
char16_t compound_onlyin_flag;
|
||||
char16_t circumfix_flag;
|
||||
char16_t forbiddenword_flag;
|
||||
char16_t keepcase_flag;
|
||||
char16_t need_affix_flag;
|
||||
char16_t warn_flag;
|
||||
|
||||
// compounding options
|
||||
char16_t compound_flag;
|
||||
char16_t compound_begin_flag;
|
||||
char16_t compound_last_flag;
|
||||
char16_t compound_middle_flag;
|
||||
Compound_Rule_Table compound_rules;
|
||||
|
||||
// spell checking options
|
||||
Break_Table break_table;
|
||||
Substr_Replacer input_substr_replacer;
|
||||
std::string ignored_chars;
|
||||
icu::Locale icu_locale;
|
||||
Substr_Replacer output_substr_replacer;
|
||||
|
||||
// suggestion options
|
||||
Replacement_Table replacements;
|
||||
std::vector<Similarity_Group> similarities;
|
||||
std::string keyboard_closeness;
|
||||
std::string try_chars;
|
||||
// Phonetic_Table phonetic_table;
|
||||
|
||||
char16_t nosuggest_flag;
|
||||
char16_t substandard_flag;
|
||||
unsigned short max_compound_suggestions;
|
||||
unsigned short max_ngram_suggestions;
|
||||
unsigned short max_diff_factor;
|
||||
bool only_max_diff;
|
||||
bool no_split_suggestions;
|
||||
bool suggest_with_dots;
|
||||
|
||||
// compounding options
|
||||
unsigned short compound_min_length;
|
||||
unsigned short compound_max_word_count;
|
||||
char16_t compound_permit_flag;
|
||||
char16_t compound_forbid_flag;
|
||||
char16_t compound_root_flag;
|
||||
char16_t compound_force_uppercase;
|
||||
bool compound_more_suffixes;
|
||||
bool compound_check_duplicate;
|
||||
bool compound_check_rep;
|
||||
bool compound_check_case;
|
||||
bool compound_check_triple;
|
||||
bool compound_simplified_triple;
|
||||
bool compound_syllable_num;
|
||||
unsigned short compound_syllable_max;
|
||||
std::string compound_syllable_vowels;
|
||||
std::vector<Compound_Pattern> compound_patterns;
|
||||
|
||||
// data members used only while parsing
|
||||
Flag_Type flag_type;
|
||||
Encoding encoding;
|
||||
std::vector<Flag_Set> flag_aliases;
|
||||
std::string wordchars; // deprecated?
|
||||
|
||||
auto parse_aff(std::istream& in) -> bool;
|
||||
auto parse_dic(std::istream& in) -> bool;
|
||||
auto parse_aff_dic(std::istream& aff, std::istream& dic)
|
||||
{
|
||||
if (parse_aff(aff))
|
||||
return parse_dic(dic);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_AFF_DATA_HXX
|
||||
2009
app/src/main/cpp/nuspell/checker.cxx
Normal file
2009
app/src/main/cpp/nuspell/checker.cxx
Normal file
File diff suppressed because it is too large
Load Diff
352
app/src/main/cpp/nuspell/checker.hxx
Normal file
352
app/src/main/cpp/nuspell/checker.hxx
Normal file
@@ -0,0 +1,352 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NUSPELL_CHECKER_HXX
|
||||
#define NUSPELL_CHECKER_HXX
|
||||
|
||||
#include "aff_data.hxx"
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
enum Affixing_Mode {
|
||||
FULL_WORD,
|
||||
AT_COMPOUND_BEGIN,
|
||||
AT_COMPOUND_END,
|
||||
AT_COMPOUND_MIDDLE
|
||||
};
|
||||
|
||||
struct Affixing_Result_Base {
|
||||
Word_List::const_pointer root_word = {};
|
||||
|
||||
operator Word_List::const_pointer() const { return root_word; }
|
||||
auto& operator*() const { return *root_word; }
|
||||
auto operator->() const { return root_word; }
|
||||
};
|
||||
|
||||
template <class T1 = void, class T2 = void>
|
||||
struct Affixing_Result : Affixing_Result_Base {
|
||||
const T1* a = {};
|
||||
const T2* b = {};
|
||||
|
||||
Affixing_Result() = default;
|
||||
Affixing_Result(Word_List::const_reference r, const T1& a, const T2& b)
|
||||
: Affixing_Result_Base{&r}, a{&a}, b{&b}
|
||||
{
|
||||
}
|
||||
};
|
||||
template <class T1>
|
||||
struct Affixing_Result<T1, void> : Affixing_Result_Base {
|
||||
const T1* a = {};
|
||||
|
||||
Affixing_Result() = default;
|
||||
Affixing_Result(Word_List::const_reference r, const T1& a)
|
||||
: Affixing_Result_Base{&r}, a{&a}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Affixing_Result<void, void> : Affixing_Result_Base {
|
||||
Affixing_Result() = default;
|
||||
Affixing_Result(Word_List::const_reference r) : Affixing_Result_Base{&r}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct Compounding_Result {
|
||||
Word_List::const_pointer word_entry = {};
|
||||
unsigned char num_words_modifier = {};
|
||||
signed char num_syllable_modifier = {};
|
||||
bool affixed_and_modified = {}; /**< non-zero affix */
|
||||
operator Word_List::const_pointer() const { return word_entry; }
|
||||
auto& operator*() const { return *word_entry; }
|
||||
auto operator->() const { return word_entry; }
|
||||
};
|
||||
|
||||
struct Checker : public Aff_Data {
|
||||
enum Forceucase : bool {
|
||||
FORBID_BAD_FORCEUCASE = false,
|
||||
ALLOW_BAD_FORCEUCASE = true
|
||||
};
|
||||
|
||||
enum Hidden_Homonym : bool {
|
||||
ACCEPT_HIDDEN_HOMONYM = false,
|
||||
SKIP_HIDDEN_HOMONYM = true
|
||||
};
|
||||
Checker()
|
||||
: Aff_Data() // we explicity do value init so content is zeroed
|
||||
{
|
||||
}
|
||||
auto spell_priv(std::string& s) const -> bool;
|
||||
auto spell_break(std::string& s, size_t depth = 0) const -> bool;
|
||||
auto spell_casing(std::string& s) const -> const Flag_Set*;
|
||||
auto spell_casing_upper(std::string& s) const -> const Flag_Set*;
|
||||
auto spell_casing_title(std::string& s) const -> const Flag_Set*;
|
||||
auto spell_sharps(std::string& base, size_t n_pos = 0, size_t n = 0,
|
||||
size_t rep = 0) const -> const Flag_Set*;
|
||||
|
||||
auto check_word(std::string& s, Forceucase allow_bad_forceucase = {},
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> const Flag_Set*;
|
||||
auto check_simple_word(std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> const Flag_Set*;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto affix_NOT_valid(const Prefix& a) const;
|
||||
template <Affixing_Mode m>
|
||||
auto affix_NOT_valid(const Suffix& a) const;
|
||||
template <Affixing_Mode m, class AffixT>
|
||||
auto outer_affix_NOT_valid(const AffixT& a) const;
|
||||
template <class AffixT>
|
||||
auto is_circumfix(const AffixT& a) const;
|
||||
template <Affixing_Mode m>
|
||||
auto is_valid_inside_compound(const Flag_Set& flags) const;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_prefix_only(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Prefix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_suffix_only(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Suffix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto
|
||||
strip_prefix_then_suffix(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Suffix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_pfx_then_sfx_2(const Prefix& pe, std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<Suffix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto
|
||||
strip_suffix_then_prefix(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Prefix, Suffix>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_sfx_then_pfx_2(const Suffix& se, std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<Prefix, Suffix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_prefix_then_suffix_commutative(
|
||||
std::string& word, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Suffix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_pfx_then_sfx_comm_2(const Prefix& pe, std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<Suffix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto
|
||||
strip_suffix_then_suffix(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Suffix, Suffix>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_sfx_then_sfx_2(const Suffix& se1, std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<Suffix, Suffix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto
|
||||
strip_prefix_then_prefix(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Prefix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_pfx_then_pfx_2(const Prefix& pe1, std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<Prefix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_prefix_then_2_suffixes(
|
||||
std::string& s, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_pfx_2_sfx_3(const Prefix& pe1, const Suffix& se1,
|
||||
std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_suffix_prefix_suffix(
|
||||
std::string& s, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_s_p_s_3(const Suffix& se1, const Prefix& pe1,
|
||||
std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_2_suffixes_then_prefix(
|
||||
std::string& s, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_2_sfx_pfx_3(const Suffix& se1, const Suffix& se2,
|
||||
std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_suffix_then_2_prefixes(
|
||||
std::string& s, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_sfx_2_pfx_3(const Suffix& se1, const Prefix& pe1,
|
||||
std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_prefix_suffix_prefix(
|
||||
std::string& word, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_p_s_p_3(const Prefix& pe1, const Suffix& se1,
|
||||
std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_2_prefixes_then_suffix(
|
||||
std::string& word, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_2_pfx_sfx_3(const Prefix& pe1, const Prefix& pe2,
|
||||
std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
auto check_compound(std::string& word,
|
||||
Forceucase allow_bad_forceucase) const
|
||||
-> Compounding_Result;
|
||||
|
||||
template <Affixing_Mode m = AT_COMPOUND_BEGIN>
|
||||
auto check_compound(std::string& word, size_t start_pos,
|
||||
size_t num_part, std::string& part,
|
||||
Forceucase allow_bad_forceucase) const
|
||||
-> Compounding_Result;
|
||||
|
||||
template <Affixing_Mode m = AT_COMPOUND_BEGIN>
|
||||
auto check_compound_classic(std::string& word, size_t start_pos,
|
||||
size_t i, size_t num_part,
|
||||
std::string& part,
|
||||
Forceucase allow_bad_forceucase) const
|
||||
-> Compounding_Result;
|
||||
|
||||
template <Affixing_Mode m = AT_COMPOUND_BEGIN>
|
||||
auto check_compound_with_pattern_replacements(
|
||||
std::string& word, size_t start_pos, size_t i, size_t num_part,
|
||||
std::string& part, Forceucase allow_bad_forceucase) const
|
||||
-> Compounding_Result;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto check_word_in_compound(std::string& s) const -> Compounding_Result;
|
||||
|
||||
auto calc_num_words_modifier(const Prefix& pfx) const -> unsigned char;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto calc_syllable_modifier(Word_List::const_reference we) const
|
||||
-> signed char;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto calc_syllable_modifier(Word_List::const_reference we,
|
||||
const Suffix& sfx) const -> signed char;
|
||||
|
||||
auto count_syllables(std::string_view word) const -> size_t;
|
||||
|
||||
auto check_compound_with_rules(std::string& word,
|
||||
std::vector<const Flag_Set*>& words_data,
|
||||
size_t start_pos, std::string& part,
|
||||
Forceucase allow_bad_forceucase) const
|
||||
|
||||
-> Compounding_Result;
|
||||
auto is_rep_similar(std::string& word) const -> bool;
|
||||
};
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto Checker::affix_NOT_valid(const Prefix& e) const
|
||||
{
|
||||
if (m == FULL_WORD && e.cont_flags.contains(compound_onlyin_flag))
|
||||
return true;
|
||||
if (m == AT_COMPOUND_END &&
|
||||
!e.cont_flags.contains(compound_permit_flag))
|
||||
return true;
|
||||
if (m != FULL_WORD && e.cont_flags.contains(compound_forbid_flag))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
template <Affixing_Mode m>
|
||||
auto Checker::affix_NOT_valid(const Suffix& e) const
|
||||
{
|
||||
if (m == FULL_WORD && e.cont_flags.contains(compound_onlyin_flag))
|
||||
return true;
|
||||
if (m == AT_COMPOUND_BEGIN &&
|
||||
!e.cont_flags.contains(compound_permit_flag))
|
||||
return true;
|
||||
if (m != FULL_WORD && e.cont_flags.contains(compound_forbid_flag))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
template <Affixing_Mode m, class AffixT>
|
||||
auto Checker::outer_affix_NOT_valid(const AffixT& e) const
|
||||
{
|
||||
if (affix_NOT_valid<m>(e))
|
||||
return true;
|
||||
if (e.cont_flags.contains(need_affix_flag))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
template <class AffixT>
|
||||
auto Checker::is_circumfix(const AffixT& a) const
|
||||
{
|
||||
return a.cont_flags.contains(circumfix_flag);
|
||||
}
|
||||
|
||||
template <class AffixInner, class AffixOuter>
|
||||
auto cross_valid_inner_outer(const AffixInner& inner, const AffixOuter& outer)
|
||||
{
|
||||
return inner.cont_flags.contains(outer.flag);
|
||||
}
|
||||
|
||||
template <class Affix>
|
||||
auto cross_valid_inner_outer(const Flag_Set& word_flags, const Affix& afx)
|
||||
{
|
||||
return word_flags.contains(afx.flag);
|
||||
}
|
||||
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_CHECKER_HXX
|
||||
1
app/src/main/cpp/nuspell/clang-format.sh
Normal file
1
app/src/main/cpp/nuspell/clang-format.sh
Normal file
@@ -0,0 +1 @@
|
||||
clang-format -style=file -i *.[ch]xx
|
||||
115
app/src/main/cpp/nuspell/dictionary.cxx
Normal file
115
app/src/main/cpp/nuspell/dictionary.cxx
Normal file
@@ -0,0 +1,115 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dictionary.hxx"
|
||||
#include "utils.hxx"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
Dictionary::Dictionary(std::istream& aff, std::istream& dic)
|
||||
{
|
||||
if (!parse_aff_dic(aff, dic))
|
||||
throw Dictionary_Loading_Error("error parsing");
|
||||
}
|
||||
|
||||
Dictionary::Dictionary() = default;
|
||||
|
||||
/**
|
||||
* @brief Create a dictionary from opened files as iostreams
|
||||
*
|
||||
* Prefer using load_from_path(). Use this if you have a specific use case,
|
||||
* like when .aff and .dic are in-memory buffers istringstream.
|
||||
*
|
||||
* @param aff The iostream of the .aff file
|
||||
* @param dic The iostream of the .dic file
|
||||
* @return Dictionary object
|
||||
* @throws Dictionary_Loading_Error on error
|
||||
*/
|
||||
auto Dictionary::load_from_aff_dic(std::istream& aff, std::istream& dic)
|
||||
-> Dictionary
|
||||
{
|
||||
return Dictionary(aff, dic);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a dictionary from files
|
||||
* @param file_path_without_extension path *without* extensions (without .dic or
|
||||
* .aff)
|
||||
* @return Dictionary object
|
||||
* @throws Dictionary_Loading_Error on error
|
||||
*/
|
||||
auto Dictionary::load_from_path(const std::string& file_path_without_extension)
|
||||
-> Dictionary
|
||||
{
|
||||
auto path = file_path_without_extension;
|
||||
path += ".aff";
|
||||
std::ifstream aff_file(path);
|
||||
if (aff_file.fail()) {
|
||||
auto err = "Aff file " + path + " not found";
|
||||
throw Dictionary_Loading_Error(err);
|
||||
}
|
||||
path.replace(path.size() - 3, 3, "dic");
|
||||
std::ifstream dic_file(path);
|
||||
if (dic_file.fail()) {
|
||||
auto err = "Dic file " + path + " not found";
|
||||
throw Dictionary_Loading_Error(err);
|
||||
}
|
||||
return load_from_aff_dic(aff_file, dic_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if a given word is correct
|
||||
* @param word any word
|
||||
* @return true if correct, false otherwise
|
||||
*/
|
||||
auto Dictionary::spell(std::string_view word) const -> bool
|
||||
{
|
||||
auto ok_enc = validate_utf8(word);
|
||||
if (unlikely(word.size() > 360))
|
||||
return false;
|
||||
if (unlikely(!ok_enc))
|
||||
return false;
|
||||
auto word_buf = string(word);
|
||||
return spell_priv(word_buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suggests correct words for a given incorrect word
|
||||
* @param[in] word incorrect word
|
||||
* @param[out] out this object will be populated with the suggestions
|
||||
*/
|
||||
auto Dictionary::suggest(std::string_view word,
|
||||
std::vector<std::string>& out) const -> void
|
||||
{
|
||||
out.clear();
|
||||
auto ok_enc = validate_utf8(word);
|
||||
if (unlikely(word.size() > 360))
|
||||
return;
|
||||
if (unlikely(!ok_enc))
|
||||
return;
|
||||
suggest_priv(word, out);
|
||||
}
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
59
app/src/main/cpp/nuspell/dictionary.hxx
Normal file
59
app/src/main/cpp/nuspell/dictionary.hxx
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Dictionary spelling.
|
||||
*/
|
||||
|
||||
#ifndef NUSPELL_DICTIONARY_HXX
|
||||
#define NUSPELL_DICTIONARY_HXX
|
||||
|
||||
#include "suggester.hxx"
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
/**
|
||||
* @brief The only important public exception
|
||||
*/
|
||||
class Dictionary_Loading_Error : public std::runtime_error {
|
||||
public:
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The only important public class
|
||||
*/
|
||||
class NUSPELL_EXPORT Dictionary : private Suggester {
|
||||
Dictionary(std::istream& aff, std::istream& dic);
|
||||
|
||||
public:
|
||||
Dictionary();
|
||||
auto static load_from_aff_dic(std::istream& aff, std::istream& dic)
|
||||
-> Dictionary;
|
||||
auto static load_from_path(
|
||||
const std::string& file_path_without_extension) -> Dictionary;
|
||||
auto spell(std::string_view word) const -> bool;
|
||||
auto suggest(std::string_view word, std::vector<std::string>& out) const
|
||||
-> void;
|
||||
};
|
||||
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_DICTIONARY_HXX
|
||||
18
app/src/main/cpp/nuspell/nuspell_export.h
Normal file
18
app/src/main/cpp/nuspell/nuspell_export.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef NUSPELL_EXPORT_H
|
||||
#define NUSPELL_EXPORT_H
|
||||
|
||||
#ifdef NUSPELL_STATIC_DEFINE
|
||||
# define NUSPELL_EXPORT
|
||||
#elif defined(_WIN32) || defined(__CYGWIN__)
|
||||
# ifdef nuspell_EXPORTS // Define this only when building Nuspell as DLL on Windows, not when using the DLL.
|
||||
# define NUSPELL_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define NUSPELL_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#elif __GNUC__ >= 4
|
||||
# define NUSPELL_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
# define NUSPELL_EXPORT
|
||||
#endif
|
||||
|
||||
#endif /* NUSPELL_EXPORT_H */
|
||||
1836
app/src/main/cpp/nuspell/structures.hxx
Normal file
1836
app/src/main/cpp/nuspell/structures.hxx
Normal file
File diff suppressed because it is too large
Load Diff
1127
app/src/main/cpp/nuspell/suggester.cxx
Normal file
1127
app/src/main/cpp/nuspell/suggester.cxx
Normal file
File diff suppressed because it is too large
Load Diff
97
app/src/main/cpp/nuspell/suggester.hxx
Normal file
97
app/src/main/cpp/nuspell/suggester.hxx
Normal file
@@ -0,0 +1,97 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NUSPELL_SUGGESTER_HXX
|
||||
#define NUSPELL_SUGGESTER_HXX
|
||||
|
||||
#include "checker.hxx"
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
struct NUSPELL_EXPORT Suggester : public Checker {
|
||||
|
||||
enum High_Quality_Sugs : bool {
|
||||
ALL_LOW_QUALITY_SUGS = false,
|
||||
HAS_HIGH_QUALITY_SUGS = true
|
||||
};
|
||||
|
||||
auto suggest_priv(std::string_view input_word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto suggest_low(std::string& word, List_Strings& out) const
|
||||
-> High_Quality_Sugs;
|
||||
|
||||
auto add_sug_if_correct(std::string& word, List_Strings& out) const
|
||||
-> bool;
|
||||
|
||||
auto uppercase_suggest(const std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto rep_suggest(std::string& word, List_Strings& out) const -> void;
|
||||
|
||||
auto try_rep_suggestion(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto max_attempts_for_long_alogs(std::string_view word) const -> size_t;
|
||||
|
||||
auto map_suggest(std::string& word, List_Strings& out) const -> void;
|
||||
|
||||
auto map_suggest(std::string& word, List_Strings& out, size_t i,
|
||||
size_t& remaining_attempts) const -> void;
|
||||
|
||||
auto adjacent_swap_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto distant_swap_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto keyboard_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto extra_char_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto forgotten_char_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto move_char_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto bad_char_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto doubled_two_chars_suggest(std::string& word,
|
||||
List_Strings& out) const -> void;
|
||||
|
||||
auto two_words_suggest(const std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto ngram_suggest(const std::string& word_u8, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto expand_root_word_for_ngram(Word_List::const_reference root,
|
||||
std::string_view wrong,
|
||||
List_Strings& expanded_list,
|
||||
std::vector<bool>& cross_affix) const
|
||||
-> void;
|
||||
};
|
||||
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_SUGGESTER_HXX
|
||||
383
app/src/main/cpp/nuspell/unicode.hxx
Normal file
383
app/src/main/cpp/nuspell/unicode.hxx
Normal file
@@ -0,0 +1,383 @@
|
||||
/* Copyright 2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef NUSPELL_UNICODE_HXX
|
||||
#define NUSPELL_UNICODE_HXX
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unicode/utf16.h>
|
||||
#include <unicode/utf8.h>
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
// UTF-8, work on malformed
|
||||
|
||||
inline constexpr auto u8_max_cp_length = U8_MAX_LENGTH;
|
||||
|
||||
auto inline u8_is_cp_error(int32_t cp) -> bool { return cp < 0; }
|
||||
|
||||
template <class Range>
|
||||
auto u8_advance_cp(const Range& str, size_t& i, int32_t& cp) -> void
|
||||
{
|
||||
using std::size, std::data;
|
||||
#if U_ICU_VERSION_MAJOR_NUM <= 60
|
||||
auto s_ptr = data(str);
|
||||
int32_t idx = i;
|
||||
int32_t len = size(str);
|
||||
U8_NEXT(s_ptr, idx, len, cp);
|
||||
i = idx;
|
||||
#else
|
||||
auto len = size(str);
|
||||
U8_NEXT(str, i, len, cp);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u8_advance_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
using std::size;
|
||||
auto len = size(str);
|
||||
U8_FWD_1(str, i, len);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u8_reverse_cp(const Range& str, size_t& i, int32_t& cp) -> void
|
||||
{
|
||||
using std::size, std::data;
|
||||
auto ptr = data(str);
|
||||
int32_t idx = i;
|
||||
U8_PREV(ptr, 0, idx, cp);
|
||||
i = idx;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u8_reverse_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
using std::size, std::data;
|
||||
auto ptr = data(str);
|
||||
int32_t idx = i;
|
||||
U8_BACK_1(ptr, 0, idx);
|
||||
i = idx;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u8_write_cp_and_advance(Range& buf, size_t& i, int32_t cp, bool& error)
|
||||
-> void
|
||||
{
|
||||
using std::size, std::data;
|
||||
#if U_ICU_VERSION_MAJOR_NUM <= 60
|
||||
auto ptr = data(buf);
|
||||
int32_t idx = i;
|
||||
int32_t len = size(buf);
|
||||
U8_APPEND(buf, idx, len, cp, error);
|
||||
i = idx;
|
||||
#else
|
||||
auto len = size(buf);
|
||||
U8_APPEND(buf, i, len, cp, error);
|
||||
#endif
|
||||
}
|
||||
|
||||
// UTF-8, valid
|
||||
|
||||
template <class Range>
|
||||
auto valid_u8_advance_cp(const Range& str, size_t& i, char32_t& cp) -> void
|
||||
{
|
||||
U8_NEXT_UNSAFE(str, i, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u8_advance_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
U8_FWD_1_UNSAFE(str, i);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u8_reverse_cp(const Range& str, size_t& i, char32_t& cp) -> void
|
||||
{
|
||||
U8_PREV_UNSAFE(str, i, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u8_reverse_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
U8_BACK_1_UNSAFE(str, i);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u8_write_cp_and_advance(Range& buf, size_t& i, char32_t cp) -> void
|
||||
{
|
||||
U8_APPEND_UNSAFE(buf, i, cp);
|
||||
}
|
||||
|
||||
// UTF-16, work on malformed
|
||||
|
||||
inline constexpr auto u16_max_cp_length = U16_MAX_LENGTH;
|
||||
|
||||
auto inline u16_is_cp_error(int32_t cp) -> bool { return U_IS_SURROGATE(cp); }
|
||||
|
||||
template <class Range>
|
||||
auto u16_advance_cp(const Range& str, size_t& i, int32_t& cp) -> void
|
||||
{
|
||||
using std::size;
|
||||
auto len = size(str);
|
||||
U16_NEXT(str, i, len, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u16_advance_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
using std::size;
|
||||
auto len = size(str);
|
||||
U16_FWD_1(str, i, len);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u16_reverse_cp(const Range& str, size_t& i, int32_t& cp) -> void
|
||||
{
|
||||
U16_PREV(str, 0, i, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u16_reverse_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
U16_BACK_1(str, 0, i);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u16_write_cp_and_advance(Range& buf, size_t& i, int32_t cp, bool& error)
|
||||
-> void
|
||||
{
|
||||
using std::size;
|
||||
auto len = size(buf);
|
||||
U16_APPEND(buf, i, len, cp, error);
|
||||
}
|
||||
|
||||
// UTF-16, valid
|
||||
|
||||
template <class Range>
|
||||
auto valid_u16_advance_cp(const Range& str, size_t& i, char32_t& cp) -> void
|
||||
{
|
||||
U16_NEXT_UNSAFE(str, i, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u16_advance_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
U16_FWD_1_UNSAFE(str, i);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u16_reverse_cp(const Range& str, size_t& i, char32_t& cp) -> void
|
||||
{
|
||||
U16_PREV_UNSAFE(str, i, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u16_reverse_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
U16_BACK_1_UNSAFE(str, i);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u16_write_cp_and_advance(Range& buf, size_t& i, char32_t cp) -> void
|
||||
{
|
||||
U16_APPEND_UNSAFE(buf, i, cp);
|
||||
}
|
||||
|
||||
// higer level funcs
|
||||
|
||||
struct U8_CP_Pos {
|
||||
size_t begin_i = 0;
|
||||
size_t end_i = begin_i;
|
||||
};
|
||||
|
||||
class U8_Encoded_CP {
|
||||
char d[u8_max_cp_length];
|
||||
int sz;
|
||||
|
||||
public:
|
||||
explicit U8_Encoded_CP(std::string_view str, U8_CP_Pos pos)
|
||||
: sz(pos.end_i - pos.begin_i)
|
||||
{
|
||||
auto i = sz;
|
||||
auto j = pos.end_i;
|
||||
auto max_len = 4;
|
||||
do {
|
||||
d[--i] = str[--j];
|
||||
} while (i && --max_len);
|
||||
}
|
||||
U8_Encoded_CP(char32_t cp)
|
||||
{
|
||||
size_t z = 0;
|
||||
valid_u8_write_cp_and_advance(d, z, cp);
|
||||
sz = z;
|
||||
}
|
||||
auto size() const noexcept -> size_t { return sz; }
|
||||
auto data() const noexcept -> const char* { return d; }
|
||||
operator std::string_view() const noexcept
|
||||
{
|
||||
return std::string_view(data(), size());
|
||||
}
|
||||
auto copy_to(std::string& str, size_t j) const
|
||||
{
|
||||
auto i = sz;
|
||||
j += sz;
|
||||
auto max_len = 4;
|
||||
do {
|
||||
str[--j] = d[--i];
|
||||
} while (i && --max_len);
|
||||
}
|
||||
};
|
||||
|
||||
auto inline u8_swap_adjacent_cp(std::string& str, size_t i1, size_t i2,
|
||||
size_t i3) -> size_t
|
||||
{
|
||||
auto cp1 = U8_Encoded_CP(str, {i1, i2});
|
||||
auto cp2 = U8_Encoded_CP(str, {i2, i3});
|
||||
auto new_i2 = i1 + std::size(cp2);
|
||||
cp1.copy_to(str, new_i2);
|
||||
cp2.copy_to(str, i1);
|
||||
return new_i2;
|
||||
}
|
||||
|
||||
auto inline u8_swap_cp(std::string& str, U8_CP_Pos pos1, U8_CP_Pos pos2)
|
||||
-> std::pair<size_t, size_t>
|
||||
{
|
||||
using std::size;
|
||||
auto cp1 = U8_Encoded_CP(str, pos1);
|
||||
auto cp2 = U8_Encoded_CP(str, pos2);
|
||||
auto new_p1_end_i = pos1.begin_i + size(cp2);
|
||||
auto new_p2_begin_i = pos2.end_i - size(cp1);
|
||||
std::char_traits<char>::move(&str[new_p1_end_i], &str[pos1.end_i],
|
||||
pos2.begin_i - pos1.end_i);
|
||||
cp2.copy_to(str, pos1.begin_i);
|
||||
cp1.copy_to(str, new_p2_begin_i);
|
||||
return {new_p1_end_i, new_p2_begin_i};
|
||||
}
|
||||
|
||||
// bellow go func without out-parametars
|
||||
|
||||
// UTF-8, can be malformed, no out-parametars
|
||||
|
||||
struct Idx_And_Next_CP {
|
||||
size_t end_i;
|
||||
int32_t cp;
|
||||
};
|
||||
|
||||
struct Idx_And_Prev_CP {
|
||||
size_t begin_i;
|
||||
int32_t cp;
|
||||
};
|
||||
|
||||
struct Write_CP_Idx_and_Error {
|
||||
size_t end_i;
|
||||
bool error;
|
||||
};
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto u8_next_cp(const Range& str, size_t i) -> Idx_And_Next_CP
|
||||
{
|
||||
int32_t cp;
|
||||
u8_advance_cp(str, i, cp);
|
||||
return {i, cp};
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto u8_next_index(const Range& str, size_t i) -> size_t
|
||||
{
|
||||
u8_advance_index(str, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto u8_prev_cp(const Range& str, size_t i) -> Idx_And_Prev_CP
|
||||
{
|
||||
int32_t cp;
|
||||
u8_reverse_cp(str, i, cp);
|
||||
return {i, cp};
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto u8_prev_index(const Range& str, size_t i) -> size_t
|
||||
{
|
||||
u8_reverse_index(str, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto u8_write_cp(Range& buf, size_t i, int32_t cp)
|
||||
-> Write_CP_Idx_and_Error
|
||||
{
|
||||
bool err;
|
||||
u8_write_cp_and_advance(buf, i, cp, err);
|
||||
return {i, err};
|
||||
}
|
||||
|
||||
// UTF-8, valid, no out-parametars
|
||||
|
||||
struct Idx_And_Next_CP_Valid {
|
||||
size_t end_i;
|
||||
char32_t cp;
|
||||
};
|
||||
|
||||
struct Idx_And_Prev_CP_Valid {
|
||||
size_t begin_i;
|
||||
char32_t cp;
|
||||
};
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto valid_u8_next_cp(const Range& str, size_t i)
|
||||
-> Idx_And_Next_CP_Valid
|
||||
{
|
||||
char32_t cp;
|
||||
valid_u8_advance_cp(str, i, cp);
|
||||
return {i, cp};
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto valid_u8_next_index(const Range& str, size_t i) -> size_t
|
||||
{
|
||||
valid_u8_advance_index(str, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto valid_u8_prev_cp(const Range& str, size_t i)
|
||||
-> Idx_And_Prev_CP_Valid
|
||||
{
|
||||
char32_t cp;
|
||||
valid_u8_reverse_cp(str, i, cp);
|
||||
return {i, cp};
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto valid_u8_prev_index(const Range& str, size_t i) -> size_t
|
||||
{
|
||||
valid_u8_reverse_index(str, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto valid_u8_write_cp(Range& buf, size_t i, int32_t cp) -> size_t
|
||||
{
|
||||
valid_u8_write_cp_and_advance(buf, i, cp);
|
||||
return i;
|
||||
}
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_UNICODE_HXX
|
||||
465
app/src/main/cpp/nuspell/utils.cxx
Normal file
465
app/src/main/cpp/nuspell/utils.cxx
Normal file
@@ -0,0 +1,465 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils.hxx"
|
||||
#include "unicode.hxx"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include <unicode/uchar.h>
|
||||
#include <unicode/ucnv.h>
|
||||
#include <unicode/unistr.h>
|
||||
#include <unicode/ustring.h>
|
||||
|
||||
#if ' ' != 32 || '.' != 46 || 'A' != 65 || 'Z' != 90 || 'a' != 97 || 'z' != 122
|
||||
#error "Basic execution character set is not ASCII"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
template <class SepT>
|
||||
static auto& split_on_any_of_low(std::string_view s, const SepT& sep,
|
||||
std::vector<std::string>& out)
|
||||
{
|
||||
size_t i1 = 0;
|
||||
size_t i2;
|
||||
do {
|
||||
i2 = s.find_first_of(sep, i1);
|
||||
out.emplace_back(s.substr(i1, i2 - i1));
|
||||
i1 = i2 + 1; // we can only add +1 if separator is single char.
|
||||
|
||||
// i2 gets s.npos after the last separator.
|
||||
// Length of i2-i1 will always go past the end. That is defined.
|
||||
} while (i2 != s.npos);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Splits string on single char seperator.
|
||||
*
|
||||
* Consecutive separators are treated as separate and will emit empty strings.
|
||||
*
|
||||
* @param s string to split.
|
||||
* @param sep char that acts as separator to split on.
|
||||
* @param out vector where separated strings are appended.
|
||||
* @return @p out.
|
||||
*/
|
||||
auto split(std::string_view s, char sep, std::vector<std::string>& out)
|
||||
-> std::vector<std::string>&
|
||||
{
|
||||
return split_on_any_of_low(s, sep, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Splits string on set of single char seperators.
|
||||
*
|
||||
* Consecutive separators are treated as separate and will emit empty strings.
|
||||
*
|
||||
* @param s string to split.
|
||||
* @param sep seperator(s) to split on.
|
||||
* @param out vector where separated strings are appended.
|
||||
* @return @p out.
|
||||
*/
|
||||
auto split_on_any_of(std::string_view s, const char* sep,
|
||||
std::vector<std::string>& out) -> std::vector<std::string>&
|
||||
{
|
||||
return split_on_any_of_low(s, sep, out);
|
||||
}
|
||||
|
||||
auto utf32_to_utf8(std::u32string_view in, std::string& out) -> void
|
||||
{
|
||||
out.clear();
|
||||
for (size_t i = 0; i != size(in); ++i) {
|
||||
auto cp = in[i];
|
||||
auto enc_cp = U8_Encoded_CP(cp);
|
||||
out += enc_cp;
|
||||
}
|
||||
}
|
||||
auto utf32_to_utf8(std::u32string_view in) -> std::string
|
||||
{
|
||||
auto out = string();
|
||||
utf32_to_utf8(in, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
auto valid_utf8_to_32(std::string_view in, std::u32string& out) -> void
|
||||
{
|
||||
out.clear();
|
||||
for (size_t i = 0; i != size(in);) {
|
||||
char32_t cp;
|
||||
valid_u8_advance_cp(in, i, cp);
|
||||
out.push_back(cp);
|
||||
}
|
||||
}
|
||||
auto valid_utf8_to_32(std::string_view in) -> std::u32string
|
||||
{
|
||||
auto out = u32string();
|
||||
valid_utf8_to_32(in, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
auto utf8_to_16(std::string_view in) -> std::u16string
|
||||
{
|
||||
auto out = u16string();
|
||||
utf8_to_16(in, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
bool utf8_to_16(std::string_view in, std::u16string& out)
|
||||
{
|
||||
int32_t len;
|
||||
auto err = U_ZERO_ERROR;
|
||||
u_strFromUTF8(data(out), size(out), &len, data(in), size(in), &err);
|
||||
out.resize(len);
|
||||
if (err == U_BUFFER_OVERFLOW_ERROR) {
|
||||
err = U_ZERO_ERROR;
|
||||
u_strFromUTF8(data(out), size(out), &len, data(in), size(in),
|
||||
&err);
|
||||
}
|
||||
if (U_SUCCESS(err))
|
||||
return true;
|
||||
out.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool validate_utf8(string_view s)
|
||||
{
|
||||
auto err = U_ZERO_ERROR;
|
||||
u_strFromUTF8(nullptr, 0, nullptr, data(s), size(s), &err);
|
||||
if (err == U_INVALID_CHAR_FOUND)
|
||||
return false;
|
||||
return err == U_BUFFER_OVERFLOW_ERROR || U_SUCCESS(err);
|
||||
}
|
||||
|
||||
auto static is_ascii(char c) -> bool
|
||||
{
|
||||
return static_cast<unsigned char>(c) <= 127;
|
||||
}
|
||||
|
||||
auto is_all_ascii(std::string_view s) -> bool
|
||||
{
|
||||
return all_of(begin(s), end(s), is_ascii);
|
||||
}
|
||||
|
||||
auto static widen_latin1(char c) -> char16_t
|
||||
{
|
||||
return static_cast<unsigned char>(c);
|
||||
}
|
||||
|
||||
auto latin1_to_ucs2(std::string_view s) -> std::u16string
|
||||
{
|
||||
u16string ret;
|
||||
latin1_to_ucs2(s, ret);
|
||||
return ret;
|
||||
}
|
||||
auto latin1_to_ucs2(std::string_view s, std::u16string& out) -> void
|
||||
{
|
||||
out.resize(s.size());
|
||||
transform(begin(s), end(s), begin(out), widen_latin1);
|
||||
}
|
||||
|
||||
auto static is_surrogate_pair(char16_t c) -> bool
|
||||
{
|
||||
return 0xD800 <= c && c <= 0xDFFF;
|
||||
}
|
||||
auto is_all_bmp(std::u16string_view s) -> bool
|
||||
{
|
||||
return none_of(begin(s), end(s), is_surrogate_pair);
|
||||
}
|
||||
|
||||
auto to_upper_ascii(std::string& s) -> void
|
||||
{
|
||||
auto& char_type = use_facet<ctype<char>>(locale::classic());
|
||||
char_type.toupper(begin_ptr(s), end_ptr(s));
|
||||
}
|
||||
|
||||
auto static utf32_to_icu(u32string_view in) -> icu::UnicodeString
|
||||
{
|
||||
static_assert(sizeof(UChar32) == sizeof(char32_t));
|
||||
return icu::UnicodeString::fromUTF32(
|
||||
reinterpret_cast<const UChar32*>(in.data()), in.size());
|
||||
}
|
||||
auto static icu_to_utf32(const icu::UnicodeString& in, std::u32string& out)
|
||||
-> bool
|
||||
{
|
||||
out.resize(in.length());
|
||||
auto err = U_ZERO_ERROR;
|
||||
auto len =
|
||||
in.toUTF32(reinterpret_cast<UChar32*>(out.data()), out.size(), err);
|
||||
if (U_SUCCESS(err)) {
|
||||
out.erase(len);
|
||||
return true;
|
||||
}
|
||||
out.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto to_upper(std::string_view in, const icu::Locale& loc) -> std::string
|
||||
{
|
||||
auto out = std::string();
|
||||
to_upper(in, loc, out);
|
||||
return out;
|
||||
}
|
||||
auto to_title(std::string_view in, const icu::Locale& loc) -> std::string
|
||||
{
|
||||
auto out = std::string();
|
||||
to_title(in, loc, out);
|
||||
return out;
|
||||
}
|
||||
auto to_lower(std::string_view in, const icu::Locale& loc) -> std::string
|
||||
{
|
||||
auto out = std::string();
|
||||
to_lower(in, loc, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
auto to_upper(string_view in, const icu::Locale& loc, string& out) -> void
|
||||
{
|
||||
auto sp = icu::StringPiece(data(in), size(in));
|
||||
auto us = icu::UnicodeString::fromUTF8(sp);
|
||||
us.toUpper(loc);
|
||||
out.clear();
|
||||
us.toUTF8String(out);
|
||||
}
|
||||
auto to_title(string_view in, const icu::Locale& loc, string& out) -> void
|
||||
{
|
||||
auto sp = icu::StringPiece(data(in), size(in));
|
||||
auto us = icu::UnicodeString::fromUTF8(sp);
|
||||
us.toTitle(nullptr, loc);
|
||||
out.clear();
|
||||
us.toUTF8String(out);
|
||||
}
|
||||
auto to_lower(u32string_view in, const icu::Locale& loc, u32string& out) -> void
|
||||
{
|
||||
auto us = utf32_to_icu(in);
|
||||
us.toLower(loc);
|
||||
icu_to_utf32(us, out);
|
||||
}
|
||||
auto to_lower(string_view in, const icu::Locale& loc, string& out) -> void
|
||||
{
|
||||
auto sp = icu::StringPiece(data(in), size(in));
|
||||
auto us = icu::UnicodeString::fromUTF8(sp);
|
||||
us.toLower(loc);
|
||||
out.clear();
|
||||
us.toUTF8String(out);
|
||||
}
|
||||
|
||||
auto to_lower_char_at(std::string& s, size_t i, const icu::Locale& loc) -> void
|
||||
{
|
||||
auto cp = valid_u8_next_cp(s, i);
|
||||
auto us = icu::UnicodeString(UChar32(cp.cp));
|
||||
us.toLower(loc);
|
||||
auto u8_low = string();
|
||||
us.toUTF8String(u8_low);
|
||||
s.replace(i, cp.end_i - i, u8_low);
|
||||
}
|
||||
auto to_title_char_at(std::string& s, size_t i, const icu::Locale& loc) -> void
|
||||
{
|
||||
auto cp = valid_u8_next_cp(s, i);
|
||||
auto us = icu::UnicodeString(UChar32(cp.cp));
|
||||
us.toTitle(nullptr, loc);
|
||||
auto u8_title = string();
|
||||
us.toUTF8String(u8_title);
|
||||
s.replace(i, cp.end_i - i, u8_title);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Determines casing (capitalization) type for a word.
|
||||
*
|
||||
* Casing is sometimes referred to as capitalization.
|
||||
*
|
||||
* @param s word.
|
||||
* @return The casing type.
|
||||
*/
|
||||
auto classify_casing(string_view s) -> Casing
|
||||
{
|
||||
size_t upper = 0;
|
||||
size_t lower = 0;
|
||||
for (size_t i = 0; i != size(s);) {
|
||||
char32_t c;
|
||||
valid_u8_advance_cp(s, i, c);
|
||||
if (u_isupper(c))
|
||||
upper++;
|
||||
else if (u_islower(c))
|
||||
lower++;
|
||||
// else neutral
|
||||
}
|
||||
if (upper == 0) // all lowercase, maybe with some neutral
|
||||
return Casing::SMALL; // most common case
|
||||
|
||||
auto first_cp = valid_u8_next_cp(s, 0);
|
||||
auto first_capital = u_isupper(first_cp.cp);
|
||||
if (first_capital && upper == 1)
|
||||
return Casing::INIT_CAPITAL; // second most common
|
||||
|
||||
if (lower == 0)
|
||||
return Casing::ALL_CAPITAL;
|
||||
|
||||
if (first_capital)
|
||||
return Casing::PASCAL;
|
||||
else
|
||||
return Casing::CAMEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Check if word[i] or word[i-1] are uppercase
|
||||
*
|
||||
* Check if the two chars are alphabetic and at least one of them is in
|
||||
* uppercase.
|
||||
*
|
||||
* @return true if at least one is uppercase, false otherwise.
|
||||
*/
|
||||
auto has_uppercase_at_compound_word_boundary(string_view word, size_t i) -> bool
|
||||
{
|
||||
auto cp = valid_u8_next_cp(word, i);
|
||||
auto cp_prev = valid_u8_prev_cp(word, i);
|
||||
if (u_isupper(cp.cp)) {
|
||||
if (u_isalpha(cp_prev.cp))
|
||||
return true;
|
||||
}
|
||||
else if (u_isupper(cp_prev.cp) && u_isalpha(cp.cp))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Encoding_Converter::Encoding_Converter(const char* enc)
|
||||
{
|
||||
auto err = UErrorCode();
|
||||
cnv = ucnv_open(enc, &err);
|
||||
}
|
||||
|
||||
Encoding_Converter::~Encoding_Converter()
|
||||
{
|
||||
if (cnv)
|
||||
ucnv_close(cnv);
|
||||
}
|
||||
|
||||
Encoding_Converter::Encoding_Converter(const Encoding_Converter& other)
|
||||
{
|
||||
auto err = UErrorCode();
|
||||
cnv = ucnv_safeClone(other.cnv, nullptr, nullptr, &err);
|
||||
}
|
||||
|
||||
auto Encoding_Converter::operator=(const Encoding_Converter& other)
|
||||
-> Encoding_Converter&
|
||||
{
|
||||
this->~Encoding_Converter();
|
||||
auto err = UErrorCode();
|
||||
cnv = ucnv_safeClone(other.cnv, nullptr, nullptr, &err);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto Encoding_Converter::to_utf8(string_view in, string& out) -> bool
|
||||
{
|
||||
if (ucnv_getType(cnv) == UCNV_UTF8) {
|
||||
if (validate_utf8(in)) {
|
||||
out = in;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
out.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
auto err = U_ZERO_ERROR;
|
||||
auto len = ucnv_toAlgorithmic(UCNV_UTF8, cnv, out.data(), out.size(),
|
||||
in.data(), in.size(), &err);
|
||||
out.resize(len);
|
||||
if (err == U_BUFFER_OVERFLOW_ERROR) {
|
||||
err = U_ZERO_ERROR;
|
||||
ucnv_toAlgorithmic(UCNV_UTF8, cnv, out.data(), out.size(),
|
||||
in.data(), in.size(), &err);
|
||||
}
|
||||
return U_SUCCESS(err);
|
||||
}
|
||||
|
||||
auto replace_ascii_char(string& s, char from, char to) -> void
|
||||
{
|
||||
for (auto i = s.find(from); i != s.npos; i = s.find(from, i + 1)) {
|
||||
s[i] = to;
|
||||
}
|
||||
}
|
||||
|
||||
auto erase_chars(string& s, string_view erase_chars) -> void
|
||||
{
|
||||
if (erase_chars.empty())
|
||||
return;
|
||||
for (size_t i = 0, next_i = 0; i != size(s); i = next_i) {
|
||||
valid_u8_advance_index(s, next_i);
|
||||
auto enc_cp = string_view(&s[i], next_i - i);
|
||||
if (erase_chars.find(enc_cp) != erase_chars.npos) {
|
||||
s.erase(i, next_i - i);
|
||||
next_i = i;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Tests if word is a number.
|
||||
*
|
||||
* Allow numbers with dot ".", dash "-" or comma "," inbetween the digits, but
|
||||
* forbids double separators such as "..", "--" and ".,".
|
||||
*/
|
||||
auto is_number(string_view s) -> bool
|
||||
{
|
||||
if (s.empty())
|
||||
return false;
|
||||
|
||||
auto it = begin(s);
|
||||
if (s[0] == '-')
|
||||
++it;
|
||||
while (it != end(s)) {
|
||||
auto next = std::find_if(
|
||||
it, end(s), [](auto c) { return c < '0' || c > '9'; });
|
||||
if (next == it)
|
||||
return false;
|
||||
if (next == end(s))
|
||||
return true;
|
||||
it = next;
|
||||
auto c = *it;
|
||||
if (c == '.' || c == ',' || c == '-')
|
||||
++it;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto count_appereances_of(string_view haystack, string_view needles) -> size_t
|
||||
{
|
||||
auto ret = size_t(0);
|
||||
for (size_t i = 0, next_i = 0; i != size(haystack); i = next_i) {
|
||||
valid_u8_advance_index(haystack, next_i);
|
||||
auto enc_cp = string_view(&haystack[i], next_i - i);
|
||||
ret += needles.find(enc_cp) != needles.npos;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
228
app/src/main/cpp/nuspell/utils.hxx
Normal file
228
app/src/main/cpp/nuspell/utils.hxx
Normal file
@@ -0,0 +1,228 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NUSPELL_UTILS_HXX
|
||||
#define NUSPELL_UTILS_HXX
|
||||
|
||||
#include "nuspell_export.h"
|
||||
|
||||
#include <clocale>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#if !defined(_WIN32) && \
|
||||
(defined(__unix__) || defined(__unix) || \
|
||||
(defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__))
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <unicode/locid.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define likely(expr) __builtin_expect(!!(expr), 1)
|
||||
#define unlikely(expr) __builtin_expect(!!(expr), 0)
|
||||
#else
|
||||
#define likely(expr) (expr)
|
||||
#define unlikely(expr) (expr)
|
||||
#endif
|
||||
|
||||
struct UConverter; // unicode/ucnv.h
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
auto split(std::string_view s, char sep, std::vector<std::string>& out)
|
||||
-> std::vector<std::string>&;
|
||||
NUSPELL_EXPORT auto split_on_any_of(std::string_view s, const char* sep,
|
||||
std::vector<std::string>& out)
|
||||
-> std::vector<std::string>&;
|
||||
|
||||
NUSPELL_EXPORT auto utf32_to_utf8(std::u32string_view in, std::string& out)
|
||||
-> void;
|
||||
NUSPELL_EXPORT auto utf32_to_utf8(std::u32string_view in) -> std::string;
|
||||
|
||||
auto valid_utf8_to_32(std::string_view in, std::u32string& out) -> void;
|
||||
auto valid_utf8_to_32(std::string_view in) -> std::u32string;
|
||||
|
||||
auto utf8_to_16(std::string_view in) -> std::u16string;
|
||||
auto utf8_to_16(std::string_view in, std::u16string& out) -> bool;
|
||||
|
||||
auto validate_utf8(std::string_view s) -> bool;
|
||||
|
||||
NUSPELL_EXPORT auto is_all_ascii(std::string_view s) -> bool;
|
||||
|
||||
NUSPELL_EXPORT auto latin1_to_ucs2(std::string_view s) -> std::u16string;
|
||||
auto latin1_to_ucs2(std::string_view s, std::u16string& out) -> void;
|
||||
|
||||
NUSPELL_EXPORT auto is_all_bmp(std::u16string_view s) -> bool;
|
||||
|
||||
auto to_upper_ascii(std::string& s) -> void;
|
||||
|
||||
[[nodiscard]] NUSPELL_EXPORT auto to_upper(std::string_view in,
|
||||
const icu::Locale& loc)
|
||||
-> std::string;
|
||||
[[nodiscard]] NUSPELL_EXPORT auto to_title(std::string_view in,
|
||||
const icu::Locale& loc)
|
||||
-> std::string;
|
||||
[[nodiscard]] NUSPELL_EXPORT auto to_lower(std::string_view in,
|
||||
const icu::Locale& loc)
|
||||
-> std::string;
|
||||
|
||||
auto to_upper(std::string_view in, const icu::Locale& loc, std::string& out)
|
||||
-> void;
|
||||
auto to_title(std::string_view in, const icu::Locale& loc, std::string& out)
|
||||
-> void;
|
||||
auto to_lower(std::u32string_view in, const icu::Locale& loc,
|
||||
std::u32string& out) -> void;
|
||||
auto to_lower(std::string_view in, const icu::Locale& loc, std::string& out)
|
||||
-> void;
|
||||
auto to_lower_char_at(std::string& s, size_t i, const icu::Locale& loc) -> void;
|
||||
auto to_title_char_at(std::string& s, size_t i, const icu::Locale& loc) -> void;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Enum that identifies the casing type of a word.
|
||||
*
|
||||
* Neutral characters like numbers are ignored, so "abc" and "abc123abc" are
|
||||
* both classified as small.
|
||||
*/
|
||||
enum class Casing : char {
|
||||
SMALL,
|
||||
INIT_CAPITAL,
|
||||
ALL_CAPITAL,
|
||||
CAMEL /**< @internal camelCase i.e. mixed case with first small */,
|
||||
PASCAL /**< @internal PascalCase i.e. mixed case with first capital */
|
||||
};
|
||||
|
||||
NUSPELL_EXPORT auto classify_casing(std::string_view s) -> Casing;
|
||||
|
||||
auto has_uppercase_at_compound_word_boundary(std::string_view word, size_t i)
|
||||
-> bool;
|
||||
|
||||
class Encoding_Converter {
|
||||
UConverter* cnv = nullptr;
|
||||
|
||||
public:
|
||||
Encoding_Converter() = default;
|
||||
explicit Encoding_Converter(const char* enc);
|
||||
explicit Encoding_Converter(const std::string& enc)
|
||||
: Encoding_Converter(enc.c_str())
|
||||
{
|
||||
}
|
||||
~Encoding_Converter();
|
||||
Encoding_Converter(const Encoding_Converter& other);
|
||||
Encoding_Converter(Encoding_Converter&& other) noexcept
|
||||
{
|
||||
cnv = other.cnv;
|
||||
cnv = nullptr;
|
||||
}
|
||||
auto operator=(const Encoding_Converter& other) -> Encoding_Converter&;
|
||||
auto operator=(Encoding_Converter&& other) noexcept
|
||||
-> Encoding_Converter&
|
||||
{
|
||||
std::swap(cnv, other.cnv);
|
||||
return *this;
|
||||
}
|
||||
auto to_utf8(std::string_view in, std::string& out) -> bool;
|
||||
auto valid() -> bool { return cnv != nullptr; }
|
||||
};
|
||||
|
||||
//#if _POSIX_VERSION >= 200809L
|
||||
#if defined(_POSIX_VERSION) && !defined(__NetBSD__) && !defined(__HAIKU__)
|
||||
class Setlocale_To_C_In_Scope {
|
||||
locale_t old_loc = nullptr;
|
||||
|
||||
public:
|
||||
Setlocale_To_C_In_Scope()
|
||||
: old_loc{uselocale(newlocale(0, "C", nullptr))}
|
||||
{
|
||||
}
|
||||
~Setlocale_To_C_In_Scope()
|
||||
{
|
||||
auto new_loc = uselocale(old_loc);
|
||||
if (new_loc != old_loc)
|
||||
freelocale(new_loc);
|
||||
}
|
||||
Setlocale_To_C_In_Scope(const Setlocale_To_C_In_Scope&) = delete;
|
||||
};
|
||||
#else
|
||||
class Setlocale_To_C_In_Scope {
|
||||
std::string old_name;
|
||||
#ifdef _WIN32
|
||||
int old_per_thread;
|
||||
#endif
|
||||
public:
|
||||
Setlocale_To_C_In_Scope() : old_name(setlocale(LC_ALL, nullptr))
|
||||
{
|
||||
#ifdef _WIN32
|
||||
old_per_thread = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
|
||||
#endif
|
||||
auto x = setlocale(LC_ALL, "C");
|
||||
if (!x)
|
||||
old_name.clear();
|
||||
}
|
||||
~Setlocale_To_C_In_Scope()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_configthreadlocale(old_per_thread);
|
||||
if (old_per_thread == _ENABLE_PER_THREAD_LOCALE)
|
||||
#endif
|
||||
{
|
||||
if (!old_name.empty())
|
||||
setlocale(LC_ALL, old_name.c_str());
|
||||
}
|
||||
}
|
||||
Setlocale_To_C_In_Scope(const Setlocale_To_C_In_Scope&) = delete;
|
||||
};
|
||||
#endif
|
||||
|
||||
auto replace_ascii_char(std::string& s, char from, char to) -> void;
|
||||
auto erase_chars(std::string& s, std::string_view erase_chars) -> void;
|
||||
NUSPELL_EXPORT auto is_number(std::string_view s) -> bool;
|
||||
auto count_appereances_of(std::string_view haystack, std::string_view needles)
|
||||
-> size_t;
|
||||
|
||||
auto inline begins_with(std::string_view haystack, std::string_view needle)
|
||||
-> bool
|
||||
{
|
||||
return haystack.compare(0, needle.size(), needle) == 0;
|
||||
}
|
||||
|
||||
auto inline ends_with(std::string_view haystack, std::string_view needle)
|
||||
-> bool
|
||||
{
|
||||
return haystack.size() >= needle.size() &&
|
||||
haystack.compare(haystack.size() - needle.size(), needle.size(),
|
||||
needle) == 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto begin_ptr(T& x)
|
||||
{
|
||||
return x.data();
|
||||
}
|
||||
template <class T>
|
||||
auto end_ptr(T& x)
|
||||
{
|
||||
return x.data() + x.size();
|
||||
}
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_UTILS_HXX
|
||||
12
app/src/main/cpp/utils/CMakeLists.txt
Normal file
12
app/src/main/cpp/utils/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
add_library(
|
||||
# Name
|
||||
utils
|
||||
|
||||
# Headers
|
||||
jni_utils.h
|
||||
log.h
|
||||
|
||||
# Sources
|
||||
jni_utils.cpp
|
||||
log.cpp
|
||||
)
|
||||
34
app/src/main/cpp/utils/jni_utils.cpp
Normal file
34
app/src/main/cpp/utils/jni_utils.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jni_utils.h"
|
||||
#include "log.h"
|
||||
|
||||
std::string utils::j2std_string(JNIEnv *env, jobject jStr) {
|
||||
auto cStr = reinterpret_cast<const char *>(env->GetDirectBufferAddress(jStr));
|
||||
auto size = env->GetDirectBufferCapacity(jStr);
|
||||
std::string stdStr(cStr, size);
|
||||
log_debug("spell j2s", stdStr);
|
||||
return stdStr;
|
||||
}
|
||||
|
||||
jobject utils::std2j_string(JNIEnv *env, const std::string& stdStr) {
|
||||
log_debug("spell s2j", stdStr);
|
||||
size_t byteCount = stdStr.length();
|
||||
auto cStr = stdStr.c_str();
|
||||
auto buffer = env->NewDirectByteBuffer((void *) cStr, byteCount);
|
||||
return buffer;
|
||||
}
|
||||
30
app/src/main/cpp/utils/jni_utils.h
Normal file
30
app/src/main/cpp/utils/jni_utils.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLORISBOARD_JNI_UTILS_H
|
||||
#define FLORISBOARD_JNI_UTILS_H
|
||||
|
||||
#include <jni.h>
|
||||
#include <string>
|
||||
|
||||
namespace utils {
|
||||
|
||||
std::string j2std_string(JNIEnv *env, jobject jStr);
|
||||
jobject std2j_string(JNIEnv *env, const std::string& in);
|
||||
|
||||
} // namespace utils
|
||||
|
||||
#endif // FLORISBOARD_JNI_UTILS_H
|
||||
81
app/src/main/cpp/utils/log.cpp
Normal file
81
app/src/main/cpp/utils/log.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android/log.h>
|
||||
#include <unistd.h>
|
||||
#include "log.h"
|
||||
|
||||
void utils::log_debug(const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(ANDROID_LOG_DEBUG, tag.c_str(), "%s", msg.c_str());
|
||||
}
|
||||
|
||||
void utils::log_info(const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(ANDROID_LOG_INFO, tag.c_str(), "%s", msg.c_str());
|
||||
}
|
||||
|
||||
void utils::log_warning(const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(ANDROID_LOG_WARN, tag.c_str(), "%s", msg.c_str());
|
||||
}
|
||||
|
||||
void utils::log_error(const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, tag.c_str(), "%s", msg.c_str());
|
||||
}
|
||||
|
||||
void utils::log_wtf(const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(ANDROID_LOG_FATAL, tag.c_str(), "%s", msg.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* Code below taken from here:
|
||||
* https://codelab.wordpress.com/2014/11/03/how-to-use-standard-output-streams-for-logging-in-android-apps/
|
||||
*/
|
||||
static int pfd[2];
|
||||
static pthread_t thr;
|
||||
static const char *tag = "myapp";
|
||||
static bool already_started = false;
|
||||
|
||||
static void *thread_func(void*) {
|
||||
ssize_t rdsz;
|
||||
char buf[2048];
|
||||
while ((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) {
|
||||
if (buf[rdsz - 1] == '\n') --rdsz;
|
||||
buf[rdsz] = 0; /* add null-terminator */
|
||||
__android_log_write(ANDROID_LOG_DEBUG, tag, buf);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int utils::start_stdout_stderr_logger(const char *app_name) {
|
||||
if (already_started) return 0;
|
||||
already_started = true;
|
||||
tag = app_name;
|
||||
|
||||
/* make stdout line-buffered and stderr unbuffered */
|
||||
setvbuf(stdout, nullptr, _IOLBF, 0);
|
||||
setvbuf(stderr, nullptr, _IONBF, 0);
|
||||
|
||||
/* create the pipe and redirect stdout and stderr */
|
||||
pipe(pfd);
|
||||
dup2(pfd[1], 1);
|
||||
dup2(pfd[1], 2);
|
||||
|
||||
/* spawn the logging thread */
|
||||
if (pthread_create(&thr, nullptr, thread_func, nullptr) != 0) {
|
||||
return -1;
|
||||
}
|
||||
pthread_detach(thr);
|
||||
return 0;
|
||||
}
|
||||
34
app/src/main/cpp/utils/log.h
Normal file
34
app/src/main/cpp/utils/log.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLORISBOARD_LOG_H
|
||||
#define FLORISBOARD_LOG_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace utils {
|
||||
|
||||
void log_debug(const std::string& tag, const std::string& msg);
|
||||
void log_info(const std::string& tag, const std::string& msg);
|
||||
void log_warning(const std::string& tag, const std::string& msg);
|
||||
void log_error(const std::string& tag, const std::string& msg);
|
||||
void log_wtf(const std::string& tag, const std::string& msg);
|
||||
|
||||
int start_stdout_stderr_logger(const char *app_name);
|
||||
|
||||
} // namespace utils
|
||||
|
||||
#endif // FLORISBOARD_LOG_H
|
||||
1
app/src/main/icu4c
Submodule
1
app/src/main/icu4c
Submodule
Submodule app/src/main/icu4c added at c434a473c5
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.patrickgold.florisboard
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.res.Configuration
|
||||
import androidx.core.os.UserManagerCompat
|
||||
import dev.patrickgold.florisboard.app.prefs.florisPreferenceModel
|
||||
import dev.patrickgold.florisboard.common.NativeStr
|
||||
import dev.patrickgold.florisboard.common.toNativeStr
|
||||
import dev.patrickgold.florisboard.crashutility.CrashUtility
|
||||
import dev.patrickgold.florisboard.debug.Flog
|
||||
import dev.patrickgold.florisboard.debug.LogTopic
|
||||
import dev.patrickgold.florisboard.debug.flogError
|
||||
import dev.patrickgold.florisboard.debug.flogInfo
|
||||
import dev.patrickgold.florisboard.ime.core.Preferences
|
||||
import dev.patrickgold.florisboard.ime.core.SubtypeManager
|
||||
import dev.patrickgold.florisboard.ime.dictionary.DictionaryManager
|
||||
import dev.patrickgold.florisboard.ime.spelling.SpellingManager
|
||||
import dev.patrickgold.florisboard.ime.theme.ThemeManager
|
||||
import dev.patrickgold.florisboard.res.AssetManager
|
||||
import dev.patrickgold.florisboard.res.FlorisRef
|
||||
import dev.patrickgold.florisboard.util.AndroidVersion
|
||||
import dev.patrickgold.jetpref.datastore.JetPrefApplication
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.Exception
|
||||
|
||||
@Suppress("unused")
|
||||
class FlorisApplication : JetPrefApplication() {
|
||||
companion object {
|
||||
private const val ICU_DATA_ASSET_PATH = "icu/icudt69l.dat"
|
||||
|
||||
private external fun nativeInitICUData(path: NativeStr): Int
|
||||
|
||||
var systemLanguage: String = "en"
|
||||
private set
|
||||
|
||||
init {
|
||||
try {
|
||||
System.loadLibrary("florisboard-native")
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
try {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.plant(Timber.DebugTree())
|
||||
}
|
||||
Flog.install(
|
||||
applicationContext = this,
|
||||
isFloggingEnabled = BuildConfig.DEBUG,
|
||||
flogTopics = LogTopic.ALL,
|
||||
flogLevels = Flog.LEVEL_ALL,
|
||||
flogOutputs = Flog.OUTPUT_CONSOLE
|
||||
)
|
||||
initICU()
|
||||
CrashUtility.install(this)
|
||||
systemLanguage = Locale.getDefault().toLanguageTag()
|
||||
val prefs by florisPreferenceModel()
|
||||
val oldPrefs = Preferences.initDefault(this)
|
||||
val assetManager = AssetManager.init(this)
|
||||
SpellingManager.init(this, FlorisRef.assets("ime/spelling/config.json"))
|
||||
SubtypeManager.init(this)
|
||||
DictionaryManager.init(this)
|
||||
ThemeManager.init(this, assetManager)
|
||||
oldPrefs.initDefaultPreferences()
|
||||
} catch (e: Exception) {
|
||||
CrashUtility.stageException(e)
|
||||
return
|
||||
}
|
||||
|
||||
/*Register a receiver so user config can be applied once device protracted storage is available*/
|
||||
if (!UserManagerCompat.isUserUnlocked(this) && AndroidVersion.ATLEAST_N) {
|
||||
registerReceiver(BootComplete(), IntentFilter(Intent.ACTION_USER_UNLOCKED))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
systemLanguage = if (AndroidVersion.ATLEAST_N) {
|
||||
newConfig.locales.get(0).toLanguageTag()
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
newConfig.locale.toLanguageTag()
|
||||
}
|
||||
}
|
||||
|
||||
fun initICU(): Boolean {
|
||||
try {
|
||||
val context = if (AndroidVersion.ATLEAST_N) {
|
||||
createDeviceProtectedStorageContext()
|
||||
} else {
|
||||
this
|
||||
}
|
||||
val androidAssetManager = context.assets ?: return false
|
||||
val dstDataFile = File(context.cacheDir, "icudt.dat")
|
||||
dstDataFile.outputStream().use { os ->
|
||||
androidAssetManager.open(ICU_DATA_ASSET_PATH).use { it.copyTo(os) }
|
||||
}
|
||||
val status = nativeInitICUData(dstDataFile.absolutePath.toNativeStr())
|
||||
return if (status != 0) {
|
||||
flogError { "Native ICU data initializing failed with error code $status!" }
|
||||
false
|
||||
} else {
|
||||
flogInfo { "Successfully loaded ICU data!" }
|
||||
true
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
flogError { e.toString() }
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
fun init() {
|
||||
CrashUtility.install(this)
|
||||
val prefs = Preferences.initDefault(this)
|
||||
val assetManager = AssetManager.init(this)
|
||||
SubtypeManager.init(this)
|
||||
DictionaryManager.init(this)
|
||||
ThemeManager.init(this, assetManager)
|
||||
prefs.initDefaultPreferences()
|
||||
}
|
||||
|
||||
private class BootComplete : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
if(Intent.ACTION_USER_UNLOCKED == intent?.action){
|
||||
try {
|
||||
(context as FlorisApplication).unregisterReceiver(this)
|
||||
context.init()
|
||||
} catch (e : Exception) {
|
||||
e.fillInStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user