Merge branch 'master' into feat/mac/mcompile_mac
47
HISTORY.md
|
|
@ -1,5 +1,52 @@
|
|||
# Keyman Version History
|
||||
|
||||
## 18.0.88 alpha 2024-08-13
|
||||
|
||||
* docs: add .kmx specification (#12163)
|
||||
|
||||
## 18.0.87 alpha 2024-08-12
|
||||
|
||||
* chore(web): drop flaky auto-test component (#12155)
|
||||
* fix(common): show description even if child projects specifies path (#12145)
|
||||
|
||||
## 18.0.86 alpha 2024-08-09
|
||||
|
||||
* chore(android): Update splash screen with SIL Tai Heritage Pro logo (#12127)
|
||||
* chore(common): Update localization for Greek Polytonic (#12112)
|
||||
* chore(common): add support for build target platform exclusions (#12113)
|
||||
* feat(common): add top-level build.sh (#12114)
|
||||
* chore(developer): start building Developer on linux,mac (#12117)
|
||||
* refactor(web): Move `common/web/recorder` → `web/src/tools/testing/recorder-core` (#12092)
|
||||
|
||||
## 18.0.85 alpha 2024-08-08
|
||||
|
||||
* fix(developer): update date for last git commit date fixture (#12122)
|
||||
* refactor(android/engine): Parse keyboards.json for FirstVoices app (#11943)
|
||||
|
||||
## 18.0.84 alpha 2024-08-07
|
||||
|
||||
* refactor(common): move kpj-related files into developer-utils (#11531)
|
||||
* refactor(common): move kps-file.ts to @keymanapp/developer-utils (#11763)
|
||||
* refactor(common): move kvks-file to @keymanapp/developer-utils (#11764)
|
||||
* refactor(common): move .keyman-touch-layout reader/writer to @keymanapp/developer-utils (#11765)
|
||||
* refactor(common): move LDML keyboard .xml reader/writer and kmx-plus builder to @keymanapp/developer-utils (#12081)
|
||||
* refactor(common): move compiler-interfaces to @keymanapp/developer-utils (#12088)
|
||||
* refactor(common): move xml2js and related deps to @keymanapp/developer-utils (#12101)
|
||||
|
||||
## 18.0.83 alpha 2024-08-06
|
||||
|
||||
* chore(common): Update history from 17.0.328 (#12093)
|
||||
* change(common/models): change model tokenization to also tokenize whitespace (#11975)
|
||||
* feat(web): support transform tokenization when given a root context (#11998)
|
||||
* change(web): track whitespace-aware tokenization for context + correction-search caching (#11979)
|
||||
* change(web): leverage tokenization to preserve punctuation and whitespace when predicting (#11997)
|
||||
* fix(web): patch up worker build to provide artifacts for its tests (#12082)
|
||||
* chore(web): move `web/src/engine/paths/` → `web/src/engine/interfaces/` (#12064)
|
||||
* chore(web): move `common/web/input-processor/` → `web/src/engine/main/` (#12066)
|
||||
* refactor(web): refactor and harmonize constants (#12072)
|
||||
* chore(common): add data versions to minimum-versions.inc.sh (#12103)
|
||||
* fix(web): fix lm-worker test broken by botched merge conflict resolution (#12104)
|
||||
|
||||
## 18.0.82 alpha 2024-08-05
|
||||
|
||||
* chore(windows): remove QIT_VSHIFTDOWN QIT _VSHIFTUP (#11973)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# License
|
||||
|
||||
Copyright (c) 2017-2022 SIL International. All rights reserved.
|
||||
Copyright (c) 2017-2024 SIL Global. All rights reserved.
|
||||
|
||||
Licensed under the MIT License.
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ Licensed under the MIT License.
|
|||
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2017-2022 SIL International
|
||||
Copyright (c) 2017-2024 SIL Global
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
# License
|
||||
|
||||
Copyright (c) SIL International.
|
||||
Copyright (c) SIL Global.
|
||||
|
||||
Keyman is an open source project distributed under the [MIT license](LICENSE.md).
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
18.0.83
|
||||
18.0.89
|
||||
|
Before Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 5 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
<item>
|
||||
<bitmap
|
||||
android:src="@drawable/sil_logo_blue_2017_1"
|
||||
android:src="@drawable/sil_logo_color_tai_heritage_pro"
|
||||
android:gravity="center"/>
|
||||
</item>
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@
|
|||
<!-- Context: Text Size dialog -->
|
||||
<string name="text_size" comment="Current text size (number)">Μέγεθος κειμένου: %1$d</string>
|
||||
<!-- Context: Text Size dialog -->
|
||||
<string name="ic_text_size_up" comment="Make text bigger">Μεγαλῶστε τὸ κείμενο</string>
|
||||
<string name="ic_text_size_up" comment="Make text bigger">Μεγαλῶστε τὴν γραμματοσειρά</string>
|
||||
<!-- Context: Text Size dialog -->
|
||||
<string name="ic_text_size_down" comment="Make text smaller">Μεγαλῶστε τὸ κείμενο</string>
|
||||
<string name="ic_text_size_down" comment="Make text smaller">Μικρύνετε τὴν γραμματοσειρά</string>
|
||||
<!-- Context: Text Size dialog -->
|
||||
<string name="ic_text_size_slider" comment="Adjust text size">Ρύθμιση μεγέθους κειμένου</string>
|
||||
<!-- Context: Clear Text dialog -->
|
||||
|
|
@ -68,7 +68,7 @@
|
|||
<!-- Context: Keyman Settings menu -->
|
||||
<string name="adjust_keyboard_height" comment="Menu action to adjust keyboard height">Μεταβολὴ ὕψους πληκτρολογίου</string>
|
||||
<!-- Context: Keyman Settings menu -->
|
||||
<string name="spacebar_caption" comment="Menu action to set the spacebar caption">Spacebar caption</string>
|
||||
<string name="spacebar_caption" comment="Menu action to set the spacebar caption">Λεζάντα πλήκτρου διαστήματος</string>
|
||||
<!-- Context: Keyman Settings menu / Spacebar caption -->
|
||||
<string name="spacebar_caption_keyboard" comment="Spacebar caption option - keyboard">Πληκτρολόγιο</string>
|
||||
<!-- Context: Keyman Settings menu / Spacebar caption -->
|
||||
|
|
@ -80,9 +80,9 @@
|
|||
<!-- Context: Keyman Settings menu / Spacebar caption hint -->
|
||||
<string name="spacebar_caption_hint_keyboard" comment="Spacebar caption hint - keyboard">\'Ονομα πληκτρολογίου στὸ πλῆκτρο διαστήματος</string>
|
||||
<!-- Context: Keyman Settings menu / Spacebar caption hint -->
|
||||
<string name="spacebar_caption_hint_language" comment="Spacebar caption hint - language">\'Ονομα γλώσσας στὸ πλῆκτρο διαστήματος</string>
|
||||
<string name="spacebar_caption_hint_language" comment="Spacebar caption hint - language">Ὄνομα γλώσσας στὸ πλῆκτρο διαστήματος</string>
|
||||
<!-- Context: Keyman Settings menu / Spacebar caption hint -->
|
||||
<string name="spacebar_caption_hint_language_keyboard" comment="Spacebar caption hint - language + keyboard">\'Ονομα πληκτρολογίου καὶ γλώσσας στὸ πλῆκτρο διαστήματος</string>
|
||||
<string name="spacebar_caption_hint_language_keyboard" comment="Spacebar caption hint - language + keyboard">Ὄνομα πληκτρολογίου καὶ γλώσσας στὸ πλῆκτρο διαστήματος</string>
|
||||
<!-- Context: Keyman Settings menu / Spacebar caption hint -->
|
||||
<string name="spacebar_caption_hint_blank" comment="Spacebar caption hint - blank">Καμμία λεζάντα στὸ πλῆκτρο διαστήματος</string>
|
||||
<!-- Context: Keyman Settings menu / Haptic feedback -->
|
||||
|
|
@ -92,13 +92,13 @@
|
|||
<!-- Context: Keyman Settings menu -->
|
||||
<string name="show_banner_on" comment="Description when toggle is on">Πρὸς ὑλοποίησιν</string>
|
||||
<!-- Context: Keyman Settings menu -->
|
||||
<string name="show_banner_off" comment="Description when toggle is off">Ὅταν εἶναι off, ἐμφανίζεται μόνο ὅταν ἔχει ἐνεργοποιηθεῖ τὸ προγνωστικὸ κείμενο</string>
|
||||
<string name="show_banner_off" comment="Description when toggle is off">OFF: ἐμφάνιση μόνον ὅταν ἔχει ἐνεργοποιηθεῖ ἡ πρόβλεψη κειμένου</string>
|
||||
<!-- Context: Keyman Settings menu -->
|
||||
<string name="show_send_crash_report" comment="permission for sending crash reports">Ἐπιτρέψτε τὴν ἀποστολὴ ἀναφορῶν κατάρρευσης μέσῳ δικτύου</string>
|
||||
<!-- Context: Keyman Settings menu -->
|
||||
<string name="show_send_crash_report_on" comment="Description when toggle is on">Ὅταν εἶναι ΟΝ, θὰ ἀποστέλλονται ἀναφορὲς κατάρρευσης</string>
|
||||
<string name="show_send_crash_report_on" comment="Description when toggle is on">ON: Ἀποστολὴ ἀναφορῶν κατάρρευσης</string>
|
||||
<!-- Context: Keyman Settings menu -->
|
||||
<string name="show_send_crash_report_off" comment="Description when toggle is off">Ὅταν εἶναι off, δὲν θὰ ἀποστέλλονται ἀναφορὲς κατάρρευσης</string>
|
||||
<string name="show_send_crash_report_off" comment="Description when toggle is off">OFF: Δὲν ἀποστέλλονται ἀναφορὲς κατάρρευσης</string>
|
||||
<!-- Context: Keyman Settings "Install Keyboard or Dictionary" menu -->
|
||||
<string name="install_from_keyman_dot_com" comment="Install package from Keyman server">Ἐγκατάσταση ἀπὸ τὸ keyman.com</string>
|
||||
<!-- Context: Keyman Settings "Install Keyboard or Dictionary" menu -->
|
||||
|
|
@ -118,9 +118,9 @@
|
|||
<!-- Context: Select Package and Select Languages menu -->
|
||||
<string name="all_languages_installed" comment="Text when all languages from a keyboard package have been installed">Ὅλες οἱ γλῶσσες ἔχουν ἤδη ἐγκατασταθεῖ</string>
|
||||
<!-- Context: Adjust Keyboard Height menu -->
|
||||
<string name="drag_the_keyboard" comment="First line of adjusting keyboard height">Σύρετε τὸ πληκτρολόγιο γιὰ νὰ ἀλλάξετε τὸ ὕψος</string>
|
||||
<string name="drag_the_keyboard" comment="First line of adjusting keyboard height">Σύρετε τὸ πληκτρολόγιο γιὰ νὰ ἀλλάξετε τὸ ὕψος του</string>
|
||||
<!-- Context: Adjust Keyboard Height menu -->
|
||||
<string name="rotate_the_device" comment="Second line of adjusting keyboard height">Περιστρέψτε τὴν συσκευὴ γιὰ λειτουργία πορτραίτου καὶ τοπίου</string>
|
||||
<string name="rotate_the_device" comment="Second line of adjusting keyboard height">Περιστρέψτε τὴν συσκευὴ γιὰ προσαρμογὴ τοῦ ὕψους σὲ λειτουργία πορτραίτου καὶ τοπίου</string>
|
||||
<!-- Context: Adjust Keyboard Height menu -->
|
||||
<string name="reset_to_defaults" comment="Button to reset to default heights">Ἐπαναφέρετε τὶς προεπιλεγμένες ρυθμίσεις</string>
|
||||
<!-- Context: Keyman Web Browser -->
|
||||
|
|
@ -150,9 +150,9 @@
|
|||
<!-- Context: KMP Package strings -->
|
||||
<string name="no_new_touch_keyboards_to_install" comment="Notification when no touch-optimized keyboards can be installed">Τὸ πακέτο πληκτρολογίου δὲν ἔχει βελτιστοποιημένα πληκτρολόγια ἀφῆς πρὸς ἐγκατάστασιν</string>
|
||||
<!-- Context: KMP Package strings -->
|
||||
<string name="no_new_predictive_text_to_install" comment="Notification when no dictionaries can be installed">Δὲν ὑπάρχει νέο προγνωστικό κείμενο πρὸς ἐγκατάστασιν</string>
|
||||
<string name="no_new_predictive_text_to_install" comment="Notification when no dictionaries can be installed">Δὲν ὑπάρχουν προγνώσεις κειμένων πρὸς ἐγκατάστασιν</string>
|
||||
<!-- Context: KMP Package strings -->
|
||||
<string name="no_targets_to_install" comment="Notification when a package doesn't contain keyboards or dictionaries">Δὲν ὑπάρχουν πληκτρολόγια ἢ προγνωστικό κείμενο πρὸς ἐγκατάστασιν</string>
|
||||
<string name="no_targets_to_install" comment="Notification when a package doesn't contain keyboards or dictionaries">Δὲν ὑπάρχουν πληκτρολόγια ἢ προγνώσεις κειμένων πρὸς ἐγκατάστασιν</string>
|
||||
<!-- Context: KMP Package strings -->
|
||||
<string name="no_associated_languages" comment="Notification when a keyboard package doesn't contain languages">Τὸ πακέτο πληκτρολογίου δὲν ἔχει σχετικὲς μὲ αὐτὸ γλῶσσες πρὸς ἐγκατάστασιν</string>
|
||||
<!-- Context: KMP Package strings -->
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
<!-- Context: Button label -->
|
||||
<string name="label_close" comment="Close a dialog">Κλεῖστε</string>
|
||||
<!-- Context: Button label. Removed in Keyman 15 -->
|
||||
<string name="label_close_keyman" comment="Close the Keyman application">Κλεῖστε τὸ Κῆμαν</string>
|
||||
<string name="label_close_keyman" comment="Close the Keyman application">Κλεῖστε τὸ Keyman</string>
|
||||
<!-- Context: Button label -->
|
||||
<string name="label_forward" comment="Button to go forward">Προχωρῆστε</string>
|
||||
<!-- Context: Button label -->
|
||||
|
|
@ -53,11 +53,11 @@
|
|||
<!-- Context: Keyboard Updates -->
|
||||
<string name="confirm_download_keyboard" comment="Confirmation to download a keyboard update">Θὰ θέλατε νὰ κατεβάσετε τὴν τελευταία ἔκδοση αὐτοῦ τοῦ πληκτρολογίου;</string>
|
||||
<!-- Context: Keyboard Updates -->
|
||||
<string name="confirm_update" comment="Confirmation to update several resources">Θά θέλατε νὰ ἐνημερώσετε τώρα πληκτρολόγια καὶ λεξικά;</string>
|
||||
<string name="confirm_update" comment="Confirmation to update several resources">Θὰ θέλατε νὰ ἐνημερώσετε τώρα πληκτρολόγια καὶ λεξικά;</string>
|
||||
<!-- Context: Keyboard Updates -->
|
||||
<string name="keyboard_updates_channel">Ἐνημερώσεις Πόρων</string>
|
||||
<string name="keyboard_updates_channel">Ἐνημερώσεις</string>
|
||||
<!-- Context: Keyboard Updates -->
|
||||
<string name="keyboard_updates_available" comment="Notification when resource updates are available">Διαθέσιμες Ἐνημερώσεις Πόρων</string>
|
||||
<string name="keyboard_updates_available" comment="Notification when resource updates are available">Διαθέσιμες Ἐνημερώσεις</string>
|
||||
<!-- Context: Keyboard Updates -->
|
||||
<string name="update_available" comment="Currently installed version of a resource with an available update">%1$s (Διαθέσιμη Ἐνημέρωση)</string>
|
||||
<!-- Context: Keyboard Updates -->
|
||||
|
|
@ -67,13 +67,13 @@
|
|||
<!-- Context: Keyboard Info and Keyboard Settings -->
|
||||
<string name="keyboard_version" comment="Label for keyboard version">Ἔκδοση πληκτρολογίου</string>
|
||||
<!-- Context: Keyboard Info and Keyboard Settings -->
|
||||
<string name="help_link" comment="Label for help link">Σύνδεσμος βοηθείας</string>
|
||||
<string name="help_link" comment="Label for help link">Βοήθεια</string>
|
||||
<!-- Context: Keyboard Info and Keyboard Settings -->
|
||||
<string name="uninstall_keyboard" comment="Label for uninstalling keyboard">Ἀπεγκαταστῆστε πληκτρολόγιο</string>
|
||||
<!-- Context: Keyboard Info and Keyboard Settings -->
|
||||
<string name="keyboard_picker_new_keyboard" comment="Mark a language name that's newly installed in keyboard list">[νέο] %1$s</string>
|
||||
<!-- Context: Keyboard Info and Keyboard Settings -->
|
||||
<string name="keyboard_qr_code" comment="QR Code description">Σαρῶστε αὐτὸν τὸν κωδικό γιὰ νὰ φορτώσετε\nαὐτὸ τὸ πληκτρολόγιο σὲ ἄλλη συσκευή</string>
|
||||
<string name="keyboard_qr_code" comment="QR Code description">Σαρῶστε αὐτὸν τὸν κωδικὸ γιὰ νὰ φορτώσετε\nαὐτὸ τὸ πληκτρολόγιο σὲ ἄλλη συσκευή</string>
|
||||
<!-- Context: Keyboard Help welcome.htm title -->
|
||||
<string name="welcome_package" comment="Title to welcome.htm page (name and version)">Καλωσορίσατε στὸ %1$s</string>
|
||||
<!-- Context: Keyboard app doesn't include FileProvider library needed to view help file -->
|
||||
|
|
@ -81,22 +81,22 @@
|
|||
<!-- Context: Fatal keyboard error. Will load default keyboard -->
|
||||
<string name="fatal_keyboard_error" comment="Fatal keyboard error (keyboard ID::packageID for language). Will load default keyboard">Μοιραῖο σφάλμα πληκτρολογίου στὸ %1$s:%2$s γιὰ τὴν %3$s γλῶσσα. Φορτώνεται προεπιλεγμένο πληκτρολόγιο.</string>
|
||||
<!-- Context: Fatal keyboard error. -->
|
||||
<string name="fatal_keyboard_error_short" comment="Error in keyboard (keyboard ID::packageID for language)."> Error in keyboard %1$s:%2$s for %3$s language.</string>
|
||||
<string name="fatal_keyboard_error_short" comment="Error in keyboard (keyboard ID::packageID for language).">Σφάλμα στὸ πληκτρολόγιο %1$s:%2$s γιὰ τὴν γλῶσσα \"%3$s\".</string>
|
||||
<!-- Context: Query for associated dictionary -->
|
||||
<string name="query_associated_model" comment="Check if there's an available dictionary to download">Ἔλεγχος συσχετισμένου λεξικοῦ πρὸς λῆψιν</string>
|
||||
<string name="cannot_query_associated_model" comment="Cannot reach server to check if there's an available dictionary to download">Ἀδυναμία συνδέσεως μὲ τὸν διακομιστὴ Κῆμαν γιὰ τὸν ἔλεγχο συσχετισμένου λεξικοῦ πρὸς λῆψιν</string>
|
||||
<string name="query_associated_model" comment="Check if there's an available dictionary to download">Ἀναζήτηση σχετικοῦ λεξικοῦ πρὸς μεταφόρτωσιν</string>
|
||||
<string name="cannot_query_associated_model" comment="Cannot reach server to check if there's an available dictionary to download">Ἀδυναμία συνδέσεως μὲ τὸν διακομιστὴ Keyman γιὰ τὴν εὕρεση σχετικοῦ λεξικοῦ πρὸς μεταφόρτωσιν</string>
|
||||
<!-- Context: Model Updates -->
|
||||
<string name="confirm_download_model" comment="Confirmation to download a dictionary update">Θὰ θέλατε νὰ κατεβάσετε τὴν τελευταία ἔκδοση αὐτοῦ τοῦ λεξικοῦ;</string>
|
||||
<!-- Context: No associated dictionary found -->
|
||||
<string name="no_associated_model" comment="Confirmation there's no available dictionary to download">Δὲν ὑπάρχει λεξικὸ πρὸς λῆψιν</string>
|
||||
<string name="no_associated_model" comment="Confirmation there's no available dictionary to download">Δὲν ὑπάρχει λεξικὸ πρὸς μεταφόρτωσιν</string>
|
||||
<!-- Context: Model Updates -->
|
||||
<string name="catalog_unavailable" comment="Notification that the cloud resource catalog can't be updated">Μὴ διαθέσιμος κατάλογος πόρων</string>
|
||||
<!-- Context: Background download messages-->
|
||||
<string name="catalog_download_start_in_background" comment="Notification that the resource catalog update will begin">Ἔχει ξεκινήσει ἐνημέρωση καταλόγου στὸ παρασκήνιο</string>
|
||||
<!-- Context: Background download messages-->
|
||||
<string name="catalog_download_is_running_in_background" comment="Notification that the resource catalog update is still downloading">Ἡ λήψη τοῦ καταλόγου συνεχίζεται· παρακαλοῦμε ξαναδοκιμάστε σὲ λίγο!</string>
|
||||
<string name="catalog_download_is_running_in_background" comment="Notification that the resource catalog update is still downloading">Ἡ μεταφόρτωση τοῦ καταλόγου συνεχίζεται· παρακαλοῦμε ξαναδοκιμάστε σὲ λίγο!</string>
|
||||
<!-- Context: Background download messages-->
|
||||
<string name="progress_message_checking_resource_is_running" comment="Progress notification that the check for a resource is still running ">Ἔλεγχος πόρου σὲ ἐξέλιξη</string>
|
||||
<string name="progress_message_checking_resource_is_running" comment="Progress notification that the check for a resource is still running ">Ἀναζήτηση πόρου σὲ ἐξέλιξη</string>
|
||||
<!-- Context: Background download messages-->
|
||||
<string name="keyboard_download_start_in_background" comment="Notification that a keyboard download has started">Ἡ λήψη τοῦ πληκτρολογίου ἔχει ξεκινήσει στὸ παρασκήνιο</string>
|
||||
<!-- Context: Background download messages-->
|
||||
|
|
@ -112,7 +112,7 @@
|
|||
<!-- Context: Background download messages -->
|
||||
<string name="download_failed" comment="Notification that a download failed">Ἡ λήψη ἀπέτυχε</string>
|
||||
<!-- Context: Background download messages -->
|
||||
<string name="failed_to_retrieve_file" comment="Failed to retrieve downloaded file">Ἀποτυχία ἀνακτήσεως ληφθέντος ἀρχείου</string>
|
||||
<string name="failed_to_retrieve_file" comment="Failed to retrieve downloaded file">Ἀποτυχία ἀνακλήσεως ληφθέντος ἀρχείου</string>
|
||||
<!-- Context: General Updates -->
|
||||
<string name="update_check_unavailable" comment="Error message when a Keyman server can't be reached">Ἀποτυχία προσβάσεως στὸν διακομιστή!</string>
|
||||
<!-- Context: General Updates -->
|
||||
|
|
@ -120,11 +120,11 @@
|
|||
<!-- Context: General Updates -->
|
||||
<string name="update_failed" comment="Notification that a resource update failed">Ἕνας ἢ περισσότεροι πόροι ἀπέτυχαν νὰ ἐνημερωθοῦν!</string>
|
||||
<!-- Context: General Updates. Removed in Keyman 17 -->
|
||||
<string name="update_success" comment="Notification that a resource update successfully updated">Οἱ πόροι ἐνημερώθηκαν ἐπιτυχῶς!</string>
|
||||
<string name="update_success" comment="Notification that a resource update successfully updated">Ὅλες οἱ ἐνημερώσεις ὁλοκληρώθηκαν ἐπιτυχῶς!</string>
|
||||
<!-- Context: Model Info -->
|
||||
<string name="model_version" comment="Title for a dictionary version">Ἔκδοση λεξικοῦ</string>
|
||||
<!-- Context: Model Info -->
|
||||
<string name="uninstall_model" comment="Label to uninstall a dictionary">Ἀπεγκαταστῆτε λεξικό</string>
|
||||
<string name="uninstall_model" comment="Label to uninstall a dictionary">Ἀπεγκαταστῆστε λεξικό</string>
|
||||
<!-- Context: Model Info -->
|
||||
<string name="confirm_delete_model" comment="Confirmation to delete a dictionary">Θὰ θέλατε νὰ διαγράψετε αὐτὸ τὸ λεξικό;</string>
|
||||
<!-- Context: Model Deleted -->
|
||||
|
|
@ -136,16 +136,16 @@
|
|||
<!-- Context: Language Settings menu strings -->
|
||||
<string name="enable_corrections" comment="Enable corrections from the suggestion banner">Ἐνεργοποιῆστε τὶς διορθώσεις</string>
|
||||
<!-- Context: Language Settings menu strings -->
|
||||
<string name="enable_predictions" comment="Enable predictions from the suggestion banner">Ἐνεργοποιῆστε προβλέψεις</string>
|
||||
<string name="enable_predictions" comment="Enable predictions from the suggestion banner">Ἐνεργοποιῆστε προβλέψεις κειμένου</string>
|
||||
<!-- Context: Language Settings menu strings -->
|
||||
<string name="model_label">Λεξικά</string>
|
||||
<string name="model_label">Λεξικό</string>
|
||||
<plurals name="model_count">
|
||||
<item quantity="one">Λεξικό</item>
|
||||
<item quantity="other">Λεξικά</item>
|
||||
</plurals>
|
||||
<!-- Context: Language Settings menu substring - Check for available dictionary -->
|
||||
<string name="check_available_model" comment="Check for available dictionary">Ἔλεγχος διαθεσίμου λεξικοῦ</string>
|
||||
<string name="check_model_online" comment="Check for dictionaries online">Ἔλεγχος λεξικῶν ὀνλάϊν</string>
|
||||
<string name="check_available_model" comment="Check for available dictionary">Ἀναζήτηση διαθεσίμου λεξικοῦ</string>
|
||||
<string name="check_model_online" comment="Check for dictionaries online">Ἀναζήτηση λεξικῶν ὀνλάϊν</string>
|
||||
<!-- Context: Language Settings menu strings -->
|
||||
<string name="model_info_header" comment="Dictionary name">Λεξικό: %1$s</string>
|
||||
<!-- Context: Language Settings menu strings -->
|
||||
|
|
|
|||
36
build.sh
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/env bash
|
||||
## START STANDARD BUILD SCRIPT INCLUDE
|
||||
# adjust relative paths as necessary
|
||||
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
. "${THIS_SCRIPT%/*}/resources/build/builder.inc.sh"
|
||||
## END STANDARD BUILD SCRIPT INCLUDE
|
||||
|
||||
builder_describe "Keyman -- all projects" \
|
||||
":common" \
|
||||
":core" \
|
||||
":android" \
|
||||
":ios" \
|
||||
":linux" \
|
||||
":mac" \
|
||||
":web" \
|
||||
":windows" \
|
||||
":developer" \
|
||||
clean \
|
||||
configure \
|
||||
build \
|
||||
test \
|
||||
install \
|
||||
publish
|
||||
|
||||
builder_describe_platform \
|
||||
:android android-studio \
|
||||
:ios mac \
|
||||
:linux linux \
|
||||
:mac mac \
|
||||
:windows win
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
builder_run_child_actions clean configure build test publish install
|
||||
|
|
@ -16,6 +16,11 @@ builder_describe "Keyman common and resources modules" \
|
|||
build \
|
||||
test
|
||||
|
||||
builder_describe_platform \
|
||||
:linux linux \
|
||||
:mac mac \
|
||||
:windows win
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
389
common/cpp/km_u16.cpp
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
/*
|
||||
* Keyman is copyright (C) SIL International. MIT License.
|
||||
*
|
||||
* std::u16string functions and string conversion utility functions
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "utfcodec.hpp"
|
||||
#include "km_u16.h"
|
||||
|
||||
/** string <- wstring
|
||||
* @brief Obtain a std::string from a std::wstring
|
||||
* @param wstr the std::wstring to be converted
|
||||
* @return a std::string
|
||||
*/
|
||||
std::string string_from_wstring(std::wstring const wstr) {
|
||||
return convert<wchar_t, char>((const std::wstring)wstr);
|
||||
}
|
||||
|
||||
/** wstring <- string
|
||||
* @brief Obtain a std::wstring from a std::string
|
||||
* @param str the std::string to be converted
|
||||
* @return a std::wstring
|
||||
*/
|
||||
std::wstring wstring_from_string(std::string const str) {
|
||||
return convert<char, wchar_t>((const std::string)str);
|
||||
}
|
||||
|
||||
/** u16string <- string
|
||||
* @brief Obtain a std::u16string from a std::string
|
||||
* @param str the std::string to be converted
|
||||
* @return a std::u16string
|
||||
*/
|
||||
std::u16string u16string_from_string(std::string const str) {
|
||||
return convert<char, char16_t>((const std::string)str);
|
||||
}
|
||||
|
||||
/** string <- u16string
|
||||
* @brief Obtain a std::string from a std::u16string
|
||||
* @param str16 the std::u16string to be converted
|
||||
* @return a std::string
|
||||
*/
|
||||
std::string string_from_u16string(std::u16string const str16) {
|
||||
return convert<char16_t, char>((const std::u16string)str16);
|
||||
}
|
||||
|
||||
/** wstring <- u16string
|
||||
* @brief Obtain a std::wstring from a std::u16string
|
||||
* @param str16 the std::u16string to be converted
|
||||
* @return a std::wstring
|
||||
*/
|
||||
std::wstring wstring_from_u16string(std::u16string const str16) {
|
||||
return convert<char16_t, wchar_t>((const std::u16string)str16);
|
||||
}
|
||||
|
||||
/** u16string <- wstring
|
||||
* @brief Obtain a std::u16string from a std::wstring
|
||||
* @param wstr the std::wstring to be converted
|
||||
* @return a std::u16string
|
||||
*/
|
||||
std::u16string u16string_from_wstring(std::wstring const wstr) {
|
||||
return convert<wchar_t, char16_t>((const std::wstring)wstr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst
|
||||
* @param dst destination
|
||||
* @param sz nr of characters to be copied
|
||||
* @param fmt source to convert and copy
|
||||
*/
|
||||
void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...) {
|
||||
wchar_t* wbuf = new wchar_t[sz];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vswprintf(wbuf, sz, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
std::u16string u16str = u16string_from_wstring(wbuf);
|
||||
u16ncpy(dst, u16str.c_str(), sz);
|
||||
delete[] wbuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert u16string to long integer
|
||||
* @param str u16string beginning with the representation of an integral number.
|
||||
* @param endptr Reference to the next character in str
|
||||
* @param base Numerical base (radix) that determines the valid characters and their interpretation
|
||||
* @return a long
|
||||
*/
|
||||
long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base) {
|
||||
auto s = string_from_u16string(str);
|
||||
char* t;
|
||||
long int result = strtol(s.c_str(), &t, base);
|
||||
if (endptr != nullptr)
|
||||
*endptr = (KMX_WCHAR*)str + (t - s.c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string toHex(int num1) {
|
||||
if (num1 == 0)
|
||||
return "0";
|
||||
int num = num1;
|
||||
std::string s = "";
|
||||
while (num) {
|
||||
int temp = num % 16;
|
||||
if (temp <= 9)
|
||||
s += (48 + temp);
|
||||
else
|
||||
s += (87 + temp);
|
||||
num = num / 16;
|
||||
}
|
||||
std::reverse(s.begin(), s.end());
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append max characters from u16string
|
||||
* @param dst Pointer to the destination array
|
||||
* @param src u16string to be appended
|
||||
* @param max Maximum number of characters to be appended.
|
||||
* @return Pointer to dst
|
||||
*/
|
||||
const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) {
|
||||
KMX_WCHAR* o = dst;
|
||||
dst = (KMX_WCHAR*)u16chr(dst, 0);
|
||||
// max -= (dst-o);
|
||||
while (*src && max > 0) {
|
||||
*dst++ = *src++;
|
||||
max--;
|
||||
}
|
||||
if (max > 0)
|
||||
*dst = 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find last '/' or '\\' in an array of char16_t
|
||||
* @param name Pointer to the source
|
||||
* @return Pointer to the last slash/backslash
|
||||
*/
|
||||
const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* name) {
|
||||
const KMX_WCHAR* cp = NULL;
|
||||
cp = u16rchr(name, '\\');
|
||||
if (cp == NULL)
|
||||
cp = u16rchr(name, '/');
|
||||
return cp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find last '/' or '\\' in an array of char
|
||||
* @param name Pointer to the source
|
||||
* @return Pointer to the last slash/backslash
|
||||
*/
|
||||
KMX_CHAR* strrchr_slash(KMX_CHAR* name) {
|
||||
KMX_CHAR* cp = NULL;
|
||||
cp = strrchr(name, '\\');
|
||||
if (cp == NULL)
|
||||
cp = strrchr(name, '/');
|
||||
return cp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Locate last occurrence of character in u16string
|
||||
* @param p Pointer to the source
|
||||
* @param ch The character to be found
|
||||
* @return A pointer to the last occurrence of character in u16str
|
||||
*/
|
||||
const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch) {
|
||||
const KMX_WCHAR* p_end = p + u16len(p) - 1;
|
||||
|
||||
if (ch == '\0')
|
||||
return p_end + 1;
|
||||
while (p_end >= p) {
|
||||
if (*p_end == ch)
|
||||
return p_end;
|
||||
p_end--;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Locate first occurrence of character in u16string
|
||||
* @param p Pointer to the source
|
||||
* @param ch The character to be found
|
||||
* @return A pointer to the first occurrence of character in u16str
|
||||
*/
|
||||
const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch) {
|
||||
while (*p) {
|
||||
if (*p == ch)
|
||||
return p;
|
||||
p++;
|
||||
}
|
||||
return ch == 0 ? p : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy the u16string pointed to by scr into the array pointed to by dst
|
||||
* @param dst Pointer to the destination
|
||||
* @param src Pointer to the source to be copied
|
||||
* @return Pointer to dst
|
||||
*/
|
||||
const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src) {
|
||||
KMX_WCHAR* o = dst;
|
||||
while (*src) {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
*dst = 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy max characters of the u16string pointed to by src into the array pointed by dst
|
||||
* @param dst Pointer to the destination
|
||||
* @param src Pointer to the source to be copied
|
||||
* @param max Maximum number of characters to be copied
|
||||
* @return Pointer to dst
|
||||
*/
|
||||
const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max) {
|
||||
KMX_WCHAR* o = dst;
|
||||
while (*src && max > 0) {
|
||||
*dst++ = *src++;
|
||||
max--;
|
||||
}
|
||||
if (max > 0) {
|
||||
*dst = 0;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the length of the u16string str
|
||||
* @param p Pointer to the source
|
||||
* @return The length of u16string
|
||||
*/
|
||||
size_t u16len(const KMX_WCHAR* p) {
|
||||
int i = 0;
|
||||
while (*p) {
|
||||
p++;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compare two u16strings
|
||||
* @param p Pointer one u16string
|
||||
* @param q Pointer another u16string
|
||||
* @return 0 if strings are equal
|
||||
* ! = 0 if unequal
|
||||
*/
|
||||
int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q) {
|
||||
while (*p && *q) {
|
||||
if (*p != *q)
|
||||
return *p - *q;
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
return *p - *q;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Case insensitive comparison of up to count characters in two strings
|
||||
* @param p Pointer one u16string
|
||||
* @param q Pointer another u16string
|
||||
* @param count Maximum number of characters to compare
|
||||
* @return 0 if strings are equal
|
||||
* ! = 0 if unequal
|
||||
*/
|
||||
int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) {
|
||||
while (*p && *q && count) {
|
||||
if (toupper(*p) != toupper(*q))
|
||||
return *p - *q;
|
||||
p++;
|
||||
q++;
|
||||
count--;
|
||||
}
|
||||
if (count)
|
||||
return *p - *q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Case insensitive comparison of two strings
|
||||
* @param p Pointer one u16string
|
||||
* @param q Pointer another u16string
|
||||
* @return 0 if strings are equal
|
||||
* ! = 0 if unequal
|
||||
*/
|
||||
int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q) {
|
||||
while (*p && *q) {
|
||||
if (toupper(*p) != toupper(*q))
|
||||
return *p - *q;
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
return *p - *q;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Comparison of up to count characters in two strings
|
||||
* @param p Pointer one u16string
|
||||
* @param q Pointer another u16string
|
||||
* @param count Maximum number of characters to compare
|
||||
* @return 0 if strings are equal
|
||||
* ! = 0 if unequal
|
||||
*/
|
||||
int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count) {
|
||||
while (*p && *q && count) {
|
||||
if (*p != *q)
|
||||
return *p - *q;
|
||||
p++;
|
||||
q++;
|
||||
count--;
|
||||
}
|
||||
if (count)
|
||||
return *p - *q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Split u16string into tokens
|
||||
* @param p Pointer to u16string to parse.
|
||||
* @param ch the delimiter character
|
||||
* @param ctx the remaining string after the first delimiter
|
||||
* @return Pointer to the first token in p
|
||||
*/
|
||||
KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR ch, KMX_WCHAR** ctx) {
|
||||
if (!p) {
|
||||
p = *ctx;
|
||||
if (!p)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KMX_WCHAR* q = p;
|
||||
while (*q && *q != ch) {
|
||||
q++;
|
||||
}
|
||||
if (*q) {
|
||||
*q = 0;
|
||||
q++;
|
||||
while (*q == ch)
|
||||
q++;
|
||||
*ctx = q;
|
||||
} else {
|
||||
*ctx = NULL;
|
||||
}
|
||||
return *p ? p : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Split u16string into tokens
|
||||
* @param p Pointer to u16string to parse.
|
||||
* @param delimiters an array of delimiter characters
|
||||
* @param ctx the remaining string after the first delimiter
|
||||
* @return Pointer to the first token in p
|
||||
*/
|
||||
KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delimiters, KMX_WCHAR** ctx) {
|
||||
if (!p) {
|
||||
p = *ctx;
|
||||
if (!p)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KMX_WCHAR* q = p;
|
||||
while (*q && !u16chr(delimiters, *q)) {
|
||||
q++;
|
||||
}
|
||||
if (*q) {
|
||||
*q = 0;
|
||||
q++;
|
||||
while (*q && u16chr(delimiters, *q))
|
||||
q++;
|
||||
*ctx = q;
|
||||
} else {
|
||||
*ctx = NULL;
|
||||
}
|
||||
return *p ? p : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a u16string to a double
|
||||
* @param str Pointer to u16string
|
||||
* @return double value equivalent to the string
|
||||
*/
|
||||
double u16tof(KMX_WCHAR* str16) {
|
||||
char* pEnd;
|
||||
std::string str = string_from_u16string(str16);
|
||||
return strtof(str.c_str(), &pEnd);
|
||||
}
|
||||
76
common/include/km_u16.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <km_types.h>
|
||||
|
||||
/** @brief Obtain a std::string from a std::wstring */
|
||||
std::string string_from_wstring(std::wstring const wstr);
|
||||
|
||||
/** @brief Obtain a std::wstring from a std::string */
|
||||
std::wstring wstring_from_string(std::string const str);
|
||||
|
||||
/** @brief Obtain a std::u16string from a std::string */
|
||||
std::u16string u16string_from_string(std::string const str);
|
||||
|
||||
/** @brief Obtain a std::string from a std::u16string */
|
||||
std::string string_from_u16string(std::u16string const str16);
|
||||
|
||||
/** @brief Obtain a std::wstring from a std::u16string */
|
||||
std::wstring wstring_from_u16string(std::u16string const str16);
|
||||
|
||||
/** @brief Obtain a std::u16string from a std::wstring */
|
||||
std::u16string u16string_from_wstring(std::wstring const wstr);
|
||||
|
||||
/** @brief Convert pointer to wchar_t to pointer to char16_t and copy sz elements into dst */
|
||||
void u16sprintf(KMX_WCHAR* dst, const size_t sz, const wchar_t* fmt, ...);
|
||||
|
||||
/** @brief Return the length of the u16string str */
|
||||
size_t u16len(const KMX_WCHAR* p);
|
||||
|
||||
/** @brief Compare two u16strings */
|
||||
int u16cmp(const KMX_WCHAR* p, const KMX_WCHAR* q);
|
||||
|
||||
/** @brief Case insensitive comparison of two strings */
|
||||
int u16icmp(const KMX_WCHAR* p, const KMX_WCHAR* q);
|
||||
|
||||
/** @brief Comparison of up to count characters in two strings */
|
||||
int u16ncmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count);
|
||||
|
||||
/** @brief Case insensitive comparison of up to count characters in two strings */
|
||||
int u16nicmp(const KMX_WCHAR* p, const KMX_WCHAR* q, size_t count);
|
||||
|
||||
/** @brief Copy max characters of the u16string pointed to by src into the array pointed to by dst */
|
||||
const KMX_WCHAR* u16ncpy(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max);
|
||||
|
||||
/** @brief Copy the u16string pointed to by src into the array pointed to by dst */
|
||||
const KMX_WCHAR* u16cpy(KMX_WCHAR* dst, const KMX_WCHAR* src);
|
||||
|
||||
/** @brief Locate last occurrence of character in u16string */
|
||||
const KMX_WCHAR* u16rchr(const KMX_WCHAR* p, KMX_WCHAR ch);
|
||||
|
||||
/** @brief Locate first occurrence of character in u16string */
|
||||
const KMX_WCHAR* u16chr(const KMX_WCHAR* p, KMX_WCHAR ch);
|
||||
|
||||
/** @brief Append max characters from u16string */
|
||||
const KMX_WCHAR* u16ncat(KMX_WCHAR* dst, const KMX_WCHAR* src, size_t max);
|
||||
|
||||
/** @brief Split u16string into tokens */
|
||||
KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR ch, KMX_WCHAR** ctx);
|
||||
|
||||
/** @brief Split u16string into tokens */
|
||||
KMX_WCHAR* u16tok(KMX_WCHAR* p, const KMX_WCHAR* delimiters, KMX_WCHAR** ctx);
|
||||
|
||||
/** @brief Convert a u16string to a double */
|
||||
long int u16tol(const KMX_WCHAR* str, KMX_WCHAR** endptr, int base);
|
||||
|
||||
/** @brief Convert a u16string to a double */
|
||||
double u16tof(KMX_WCHAR* str);
|
||||
|
||||
/** @brief find last '/' or '\\' in an array of char */
|
||||
KMX_CHAR* strrchr_slash(KMX_CHAR* Name);
|
||||
|
||||
/** @brief find last '/' or '\\' in an array of char16_t */
|
||||
const KMX_WCHAR* u16rchr_slash(KMX_WCHAR const* Name);
|
||||
|
||||
std::string toHex(int num1);
|
||||
|
|
@ -16,7 +16,7 @@ BUNDLE_CMD="node ${KEYMAN_ROOT}/common/web/es-bundling/build/common-bundle.mjs"
|
|||
|
||||
builder_describe \
|
||||
"Compiles the web-oriented utility function module." \
|
||||
"@/common/web/recorder test" \
|
||||
"@/web/src/tools/testing/recorder-core test" \
|
||||
"@/common/web/keyman-version" \
|
||||
"@/common/web/es-bundling" \
|
||||
"@/common/web/types" \
|
||||
|
|
|
|||
|
|
@ -200,11 +200,9 @@ describe('ModelCompositor', function() {
|
|||
// secondary corrections may be found
|
||||
// - It's possible to interrupt "too late" if the correction search proceeds quickly,
|
||||
// returning a standard full set.
|
||||
const terminatedSuggestions = await firstPredict;
|
||||
await firstPredict;
|
||||
const finalSuggestions = await secondPredict;
|
||||
if(terminatedSuggestions.length > 0) {
|
||||
assert.isOk(terminatedSuggestions.find((entry) => entry.displayAs == 'a'));
|
||||
}
|
||||
|
||||
assert.isOk(finalSuggestions.find((entry) => entry.displayAs == 'applied'));
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"extends": "../tsconfig.kmw-main-base.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"types": ["node"],
|
||||
"baseUrl": "./",
|
||||
"outDir": "build/obj/",
|
||||
"tsBuildInfoFile": "build/obj/tsconfig.tsbuildinfo",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
|
||||
"references": [
|
||||
{ "path": "../keyman-version" },
|
||||
{ "path": "../utils/" },
|
||||
{ "path": "../keyboard-processor/" },
|
||||
{ "path": "../lm-message-types" }
|
||||
],
|
||||
}
|
||||
|
|
@ -73,40 +73,25 @@ function compile_schemas() {
|
|||
node tools/schema-bundler.js
|
||||
}
|
||||
|
||||
function copy_cldr_imports() {
|
||||
# Store CLDR imports
|
||||
# load all versions that have a cldr_info.json
|
||||
for CLDR_INFO_PATH in "$KEYMAN_ROOT/resources/standards-data/ldml-keyboards/"*/cldr_info.json
|
||||
do
|
||||
# TODO-LDML: developer/src/inst/download.in.mak needs these also...
|
||||
CLDR_PATH=$(dirname "$CLDR_INFO_PATH")
|
||||
CLDR_VER=$(basename "$CLDR_PATH")
|
||||
mkdir -p "$THIS_SCRIPT_PATH/build/src/import/$CLDR_VER"
|
||||
# TODO-LDML: When these are copied, the DOCTYPE will break due to the wrong path. We don't use the DTD so it should be OK.
|
||||
cp "$CLDR_INFO_PATH" "$CLDR_PATH/import/"*.xml "$THIS_SCRIPT_PATH/build/src/import/$CLDR_VER/"
|
||||
done
|
||||
}
|
||||
|
||||
function do_configure() {
|
||||
compile_schemas
|
||||
verify_npm_setup
|
||||
}
|
||||
|
||||
function do_build() {
|
||||
copy_cldr_imports
|
||||
tsc --build
|
||||
}
|
||||
|
||||
function do_test() {
|
||||
eslint .
|
||||
tsc --build test
|
||||
c8 --skip-full --reporter=lcov --reporter=text mocha "${builder_extra_params[@]}"
|
||||
readonly C8_THRESHOLD=50
|
||||
c8 -skip-full --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha "${builder_extra_params[@]}"
|
||||
builder_echo warning "Coverage thresholds are currently $C8_THRESHOLD%, which is lower than ideal."
|
||||
builder_echo warning "Please increase threshold in build.sh as test coverage improves."
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo
|
||||
builder_run_action configure do_configure
|
||||
builder_run_action build do_build
|
||||
builder_run_action build tsc --build
|
||||
builder_run_action test do_test
|
||||
builder_run_action publish builder_publish_npm
|
||||
|
|
|
|||
|
|
@ -31,24 +31,17 @@
|
|||
"dependencies": {
|
||||
"@keymanapp/ldml-keyboard-constants": "*",
|
||||
"@keymanapp/keyman-version": "*",
|
||||
"restructure": "3.0.1",
|
||||
"semver": "^7.5.2",
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
"restructure": "3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.1.7",
|
||||
"@types/git-diff": "^2.0.3",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^20.4.1",
|
||||
"@types/semver": "^7.3.12",
|
||||
"@types/xml2js": "^0.4.5",
|
||||
"ajv": "^8.12.0",
|
||||
"ajv-cli": "^5.0.0",
|
||||
"ajv-formats": "^2.1.1",
|
||||
"c8": "^7.12.0",
|
||||
"chalk": "^2.4.2",
|
||||
"git-diff": "^2.0.6",
|
||||
"hexy": "^0.3.4",
|
||||
"mocha": "^8.4.0",
|
||||
"typescript": "^5.4.5"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { constants } from '@keymanapp/ldml-keyboard-constants';
|
||||
import { DependencySections, StrsItem, UsetItem } from './kmx-plus.js';
|
||||
import { ElementParser, ElementSegment, ElementType } from '../ldml-keyboard/pattern-parser.js';
|
||||
import { MATCH_HEX_ESCAPE } from '../util/consts.js';
|
||||
import { unescapeOneQuadString } from '../util/util.js';
|
||||
import { ElementParser, ElementSegment, ElementType } from '../../ldml-keyboard/pattern-parser.js';
|
||||
import { util } from '@keymanapp/common-types';
|
||||
import MATCH_HEX_ESCAPE = util.MATCH_HEX_ESCAPE;
|
||||
import unescapeOneQuadString = util.unescapeOneQuadString;
|
||||
|
||||
export enum ElemElementFlags {
|
||||
none = 0,
|
||||
|
|
@ -1,12 +1,18 @@
|
|||
import { constants } from '@keymanapp/ldml-keyboard-constants';
|
||||
import * as r from 'restructure';
|
||||
import { ElementString } from './element-string.js';
|
||||
import { ListItem } from './string-list.js';
|
||||
import { isOneChar, toOneChar, unescapeString, escapeStringForRegex } from '../util/util.js';
|
||||
import { KMXFile } from './kmx.js';
|
||||
import { UnicodeSetParser, UnicodeSet } from '@keymanapp/common-types';
|
||||
import { VariableParser } from '../ldml-keyboard/pattern-parser.js';
|
||||
import { MarkerParser } from '../ldml-keyboard/pattern-parser.js';
|
||||
import { ListItem } from '../../ldml-keyboard/string-list.js';
|
||||
import { util } from '@keymanapp/common-types';
|
||||
import { KMX } from '@keymanapp/common-types';
|
||||
import { UnicodeSetParser, UnicodeSet } from '../../ldml-keyboard/unicodeset-parser-api.js';
|
||||
import { VariableParser } from '../../ldml-keyboard/pattern-parser.js';
|
||||
import { MarkerParser } from '../../ldml-keyboard/pattern-parser.js';
|
||||
|
||||
import isOneChar = util.isOneChar;
|
||||
import toOneChar = util.toOneChar;
|
||||
import unescapeString = util.unescapeString;
|
||||
import escapeStringForRegex = util.escapeStringForRegex;
|
||||
import KMXFile = KMX.KMXFile;
|
||||
|
||||
// Implementation of file structures from /core/src/ldml/C7043_ldml.md
|
||||
// Writer in kmx-builder.ts
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { OrderedStringList } from '../ldml-keyboard/pattern-parser.js';
|
||||
import { DependencySections, StrsItem, StrsOptions } from './kmx-plus.js';
|
||||
import { OrderedStringList } from './pattern-parser.js';
|
||||
import { DependencySections, StrsItem, StrsOptions } from '../kmx/kmx-plus/kmx-plus.js';
|
||||
|
||||
/**
|
||||
* A single entry in a ListItem.
|
||||
|
|
@ -1,55 +1,19 @@
|
|||
export * as KMX from './kmx/kmx.js';
|
||||
export * as KMXPlus from './kmx/kmx-plus.js';
|
||||
export { default as KMXBuilder } from './kmx/kmx-builder.js';
|
||||
export { KmxFileReader, KmxFileReaderError } from './kmx/kmx-file-reader.js';
|
||||
export * as KeymanTargets from './kmx/keyman-targets.js';
|
||||
|
||||
export * as VisualKeyboard from './kvk/visual-keyboard.js';
|
||||
export { default as KMXPlusBuilder} from './kmx/kmx-plus-builder/kmx-plus-builder.js';
|
||||
export { default as KvkFileReader } from './kvk/kvk-file-reader.js';
|
||||
export { default as KvksFileReader } from './kvk/kvks-file-reader.js';
|
||||
export { default as KvkFileWriter } from './kvk/kvk-file-writer.js';
|
||||
export { default as KvksFileWriter } from './kvk/kvks-file-writer.js';
|
||||
export * as KvkFile from './kvk/kvk-file.js';
|
||||
export * as KvksFile from './kvk/kvks-file.js';
|
||||
|
||||
export * as LDMLKeyboard from './ldml-keyboard/ldml-keyboard-xml.js';
|
||||
export { LDMLKeyboardTestDataXMLSourceFile } from './ldml-keyboard/ldml-keyboard-testdata-xml.js';
|
||||
export { UnicodeSetParser, UnicodeSet } from './ldml-keyboard/unicodeset-parser-api.js';
|
||||
export { VariableParser, MarkerParser } from './ldml-keyboard/pattern-parser.js';
|
||||
export { LDMLKeyboardXMLSourceFileReader, LDMLKeyboardXMLSourceFileReaderOptions } from './ldml-keyboard/ldml-keyboard-xml-reader.js';
|
||||
|
||||
export { USVirtualKeyCodes } from './consts/virtual-key-constants.js';
|
||||
export * as Constants from './consts/virtual-key-constants.js';
|
||||
export { ModifierKeyConstants } from './consts/modifier-key-constants.js';
|
||||
|
||||
export { defaultCompilerOptions, CompilerBaseOptions, CompilerCallbacks, CompilerOptions, CompilerEvent, CompilerErrorNamespace,
|
||||
CompilerErrorSeverity, CompilerPathCallbacks, CompilerFileSystemCallbacks, CompilerCallbackOptions,
|
||||
CompilerError, CompilerMessageSpec, CompilerMessageSpecWithException, compilerErrorSeverity, CompilerErrorMask, CompilerFileCallbacks, compilerErrorSeverityName,
|
||||
compilerErrorFormatCode, CompilerMessageDef,
|
||||
compilerLogLevelToSeverity, CompilerLogLevel, compilerEventFormat, ALL_COMPILER_LOG_LEVELS,
|
||||
ALL_COMPILER_LOG_FORMATS, CompilerLogFormat,
|
||||
CompilerMessageOverride,
|
||||
CompilerMessageOverrideMap,
|
||||
|
||||
KeymanCompilerArtifact,
|
||||
KeymanCompilerArtifactOptional,
|
||||
KeymanCompilerArtifacts,
|
||||
KeymanCompilerResult,
|
||||
KeymanCompiler
|
||||
|
||||
} from './util/compiler-interfaces.js';
|
||||
export { CommonTypesMessages } from './util/common-events.js';
|
||||
|
||||
export * as TouchLayout from './keyman-touch-layout/keyman-touch-layout-file.js';
|
||||
export { TouchLayoutFileReader } from './keyman-touch-layout/keyman-touch-layout-file-reader.js';
|
||||
export { TouchLayoutFileWriter, TouchLayoutFileWriterOptions } from './keyman-touch-layout/keyman-touch-layout-file-writer.js';
|
||||
|
||||
export * as KPJ from './kpj/kpj-file.js';
|
||||
export { KPJFileReader } from './kpj/kpj-file-reader.js';
|
||||
export { KeymanDeveloperProject, KeymanDeveloperProjectFile, KeymanDeveloperProjectType, } from './kpj/keyman-developer-project.js';
|
||||
|
||||
export * as KpsFile from './package/kps-file.js';
|
||||
export * as KmpJsonFile from './package/kmp-json-file.js';
|
||||
|
||||
export { Uni_IsSurrogate1, Uni_IsSurrogate2 } from './util/util.js';
|
||||
|
|
@ -60,4 +24,8 @@ export * as KeymanFileTypes from './util/file-types.js';
|
|||
export * as Schemas from './schemas.js';
|
||||
export * as SchemaValidators from './schema-validators.js';
|
||||
|
||||
export * as xml2js from './deps/xml2js/xml2js.js';
|
||||
export * as KMXPlus from './kmx/kmx-plus/kmx-plus.js';
|
||||
// TODO: these exports are really not well named
|
||||
export { UnicodeSetParser, UnicodeSet } from './ldml-keyboard/unicodeset-parser-api.js';
|
||||
export { VariableParser, MarkerParser } from './ldml-keyboard/pattern-parser.js';
|
||||
export { ElementString } from './kmx/kmx-plus/element-string.js';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
/**
|
||||
|
|
@ -12,26 +11,3 @@ import { fileURLToPath } from "url";
|
|||
export function makePathToFixture(...components: string[]): string {
|
||||
return fileURLToPath(new URL(path.join('..', '..', '..', 'test', 'fixtures', ...components), import.meta.url));
|
||||
}
|
||||
|
||||
export function loadFile(filename: string | URL): Buffer {
|
||||
return fs.readFileSync(filename);
|
||||
}
|
||||
|
||||
export function resolveFilename(baseFilename: string, filename: string) {
|
||||
const basePath =
|
||||
baseFilename.endsWith('/') || baseFilename.endsWith('\\') ?
|
||||
baseFilename :
|
||||
path.dirname(baseFilename);
|
||||
// Transform separators to platform separators -- we are agnostic
|
||||
// in our use here but path prefers files may use
|
||||
// either / or \, although older kps files were always \.
|
||||
if(path.sep == '/') {
|
||||
filename = filename.replace(/\\/g, '/');
|
||||
} else {
|
||||
filename = filename.replace(/\//g, '\\');
|
||||
}
|
||||
if(!path.isAbsolute(filename)) {
|
||||
filename = path.resolve(basePath, filename);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
"preserveConstEnums": true,
|
||||
},
|
||||
"include": [
|
||||
"src/deps/xml2js/*.js",
|
||||
"src/**/*.ts",
|
||||
"src/schemas/*.mjs", // Import the validators
|
||||
],
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ if hotdoc.found()
|
|||
deps = files(
|
||||
'../include/keyman/keyman_core_api.h',
|
||||
'../src/jsonpp.hpp',
|
||||
'../src/utfcodec.hpp'
|
||||
'../../common/cpp/utfcodec.hpp'
|
||||
)
|
||||
|
||||
docs = custom_target('docs',
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ core_files = files(
|
|||
'keyboard.cpp',
|
||||
'state.cpp',
|
||||
'jsonpp.cpp',
|
||||
'utfcodec.cpp',
|
||||
'../../common/cpp/utfcodec.cpp',
|
||||
)
|
||||
|
||||
mock_files = files(
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@
|
|||
cmpfiles = ['-c', 'import sys; a = open(sys.argv[1], \'r\').read(); b = open(sys.argv[2], \'r\').read(); exit(not (a==b))']
|
||||
stnds = join_paths(meson.current_source_dir(), 'standards')
|
||||
|
||||
libsrc = include_directories(join_paths('../', 'src'))
|
||||
libsrc = include_directories(
|
||||
'../src',
|
||||
'../../common/include'
|
||||
)
|
||||
|
||||
# kmx_test_source is required for linux builds, so always enable it even when we
|
||||
# disable all other tests
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@
|
|||
#
|
||||
|
||||
e = executable('utftest', 'utftest.cpp',
|
||||
objects: lib.extract_objects('utfcodec.cpp'),
|
||||
objects: lib.extract_objects('../../common/cpp/utfcodec.cpp'),
|
||||
include_directories: [libsrc])
|
||||
test('utftest', e)
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ files:
|
|||
languages_mapping:
|
||||
osx_code:
|
||||
pt-PT: pt-PT.lproj
|
||||
el-polyton: el.lproj
|
||||
|
||||
- source: /mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/en.lproj/preferences.strings
|
||||
dest: /mac/app/preferences.strings
|
||||
|
|
@ -134,6 +135,7 @@ files:
|
|||
languages_mapping:
|
||||
osx_code:
|
||||
pt-PT: pt-PT.lproj
|
||||
el-polyton: el.lproj
|
||||
|
||||
- source: /mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/en.lproj/KMInfoWindowController.strings
|
||||
dest: /mac/app/KMInfoWindowController.strings
|
||||
|
|
@ -141,6 +143,7 @@ files:
|
|||
languages_mapping:
|
||||
osx_code:
|
||||
pt-PT: pt-PT.lproj
|
||||
el-polyton: el.lproj
|
||||
|
||||
- source: /mac/Keyman4MacIM/Keyman4MacIM/KMKeyboardHelpWindow/en.lproj/KMKeyboardHelpWindowController.strings
|
||||
dest: /mac/app/KMKeyboardHelpWindowController.strings
|
||||
|
|
@ -148,6 +151,7 @@ files:
|
|||
languages_mapping:
|
||||
osx_code:
|
||||
pt-PT: pt-PT.lproj
|
||||
el-polyton: el.lproj
|
||||
|
||||
- source: /mac/Keyman4MacIM/Keyman4MacIM/en.lproj/Localizable.strings
|
||||
dest: /mac/app/Localizable.strings
|
||||
|
|
@ -155,6 +159,7 @@ files:
|
|||
languages_mapping:
|
||||
osx_code:
|
||||
pt-PT: pt-PT.lproj
|
||||
el-polyton: el.lproj
|
||||
|
||||
- source: /mac/Keyman4MacIM/Keyman4MacIM/en.lproj/MainMenu.strings
|
||||
dest: /mac/app/MainMenu.strings
|
||||
|
|
@ -162,6 +167,7 @@ files:
|
|||
languages_mapping:
|
||||
osx_code:
|
||||
pt-PT: pt-PT.lproj
|
||||
el-polyton: el.lproj
|
||||
|
||||
# crowdin parameters descriptions:
|
||||
|
||||
|
|
|
|||
1
developer/src/.build-builder
Normal file
|
|
@ -0,0 +1 @@
|
|||
The presence of this file tells CI that we can build Developer on mac and linux, as of 18.0. We will be able to remove this file in 19.0.
|
||||
|
|
@ -42,11 +42,29 @@ builder_describe \
|
|||
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
|
||||
"--dry-run,-n+ Don't actually publish anything to external endpoints, just dry run"
|
||||
|
||||
builder_describe_platform \
|
||||
:ext win,delphi \
|
||||
:kmanalyze win \
|
||||
:kmdbrowserhost win,delphi \
|
||||
:kmdecomp win \
|
||||
:kmconvert win,delphi \
|
||||
:samples win \
|
||||
:server win \
|
||||
:setup win,delphi \
|
||||
:test win,delphi \
|
||||
:tike win,delphi \
|
||||
:inst win,delphi
|
||||
|
||||
# TODO: in future :server could be built on other platforms, potentially, but it
|
||||
# has addons that are Windows-specific currently
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh"
|
||||
if [[ $BUILDER_OS == win ]]; then
|
||||
source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh"
|
||||
fi
|
||||
|
||||
#
|
||||
# We want to do some checks before we head down the long publish path
|
||||
|
|
|
|||
|
|
@ -11,5 +11,8 @@ builder_describe \
|
|||
":delphi Delphi components" \
|
||||
":web Web components"
|
||||
|
||||
builder_describe_platform \
|
||||
:delphi win,delphi
|
||||
|
||||
builder_parse "$@"
|
||||
builder_run_child_actions clean configure build test
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
|
|||
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
|
||||
|
||||
builder_describe "Keyman Developer unit test helpers" \
|
||||
"@/common/web/types" \
|
||||
"@/developer/src/common/web/utils" \
|
||||
clean configure build test
|
||||
|
||||
builder_describe_outputs \
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { CompilerEvent, CompilerCallbacks, CompilerPathCallbacks, CompilerFileSystemCallbacks, CompilerError } from '@keymanapp/common-types';
|
||||
import { CompilerEvent, CompilerCallbacks, CompilerPathCallbacks, CompilerFileSystemCallbacks, CompilerError } from '@keymanapp/developer-utils';
|
||||
export { verifyCompilerMessagesObject } from './verifyCompilerMessagesObject.js';
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -17,6 +17,6 @@
|
|||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@keymanapp/common-types": "*"
|
||||
"@keymanapp/developer-utils": "*"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { CompilerError, CompilerErrorMask } from '@keymanapp/common-types';
|
||||
import { CompilerError, CompilerErrorMask } from '@keymanapp/developer-utils';
|
||||
import {assert, expect} from 'chai';
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -21,20 +21,42 @@ builder_describe "Build Keyman Developer web utility module" \
|
|||
|
||||
builder_describe_outputs \
|
||||
configure /node_modules \
|
||||
build /developer/src/common/web/utils/build/index.js
|
||||
build /developer/src/common/web/utils/build/src/index.js
|
||||
|
||||
builder_parse "$@"
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
function copy_cldr_imports() {
|
||||
# Store CLDR imports
|
||||
# load all versions that have a cldr_info.json
|
||||
for CLDR_INFO_PATH in "$KEYMAN_ROOT/resources/standards-data/ldml-keyboards/"*/cldr_info.json
|
||||
do
|
||||
# TODO-LDML: developer/src/inst/download.in.mak needs these also...
|
||||
CLDR_PATH=$(dirname "$CLDR_INFO_PATH")
|
||||
CLDR_VER=$(basename "$CLDR_PATH")
|
||||
mkdir -p "$THIS_SCRIPT_PATH/build/src/import/$CLDR_VER"
|
||||
# TODO-LDML: When these are copied, the DOCTYPE will break due to the wrong path. We don't use the DTD so it should be OK.
|
||||
cp "$CLDR_INFO_PATH" "$CLDR_PATH/import/"*.xml "$THIS_SCRIPT_PATH/build/src/import/$CLDR_VER/"
|
||||
done
|
||||
}
|
||||
|
||||
function do_build() {
|
||||
copy_cldr_imports
|
||||
tsc --build
|
||||
}
|
||||
|
||||
builder_run_action clean rm -rf ./build/
|
||||
builder_run_action configure verify_npm_setup
|
||||
builder_run_action build tsc --build
|
||||
builder_run_action build do_build
|
||||
|
||||
if builder_start_action test; then
|
||||
eslint .
|
||||
tsc --build test
|
||||
c8 --reporter=lcov --reporter=text --exclude-after-remap mocha
|
||||
readonly C8_THRESHOLD=40
|
||||
c8 --reporter=lcov --reporter=text --exclude-after-remap --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha
|
||||
builder_echo warning "Coverage thresholds are currently $C8_THRESHOLD%, which is lower than ideal."
|
||||
builder_echo warning "Please increase threshold in build.sh as test coverage improves."
|
||||
builder_finish_action success test
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
export { validateMITLicense } from './src/validate-mit-license.js';
|
||||
export { KeymanSentry, SentryNodeOptions } from './src/KeymanSentry.js';
|
||||
export { getOption, loadOptions, clearOptions } from './src/options.js';
|
||||
export { escapeMarkdownChar } from './src/markdown.js';
|
||||
export { KeymanUrls } from './src/keyman-urls.js';
|
||||
export { isValidEmail } from './src/is-valid-email.js';
|
||||
|
|
@ -3,19 +3,29 @@
|
|||
"description": "Keyman Developer utilities",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./build/index.js"
|
||||
".": "./build/src/index.js"
|
||||
},
|
||||
"files": [
|
||||
"/build/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@sentry/node": "^7.57.0"
|
||||
"@sentry/node": "^7.57.0",
|
||||
"@keymanapp/common-types": "*",
|
||||
"eventemitter3": "^5.0.0",
|
||||
"restructure": "^3.0.1",
|
||||
"semver": "^7.5.2",
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/git-diff": "^2.0.3",
|
||||
"@types/node": "^20.4.1",
|
||||
"typescript": "^5.4.5",
|
||||
"@types/semver": "^7.3.12",
|
||||
"@types/xml2js": "^0.4.5",
|
||||
"c8": "^7.12.0",
|
||||
"mocha": "^8.4.0"
|
||||
"git-diff": "^2.0.6",
|
||||
"mocha": "^8.4.0",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -b"
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ export class CompilerError {
|
|||
*/
|
||||
static severityNameToValue(name: string): CompilerErrorSeverity {
|
||||
name = name.toLowerCase();
|
||||
for(let level of CompilerErrorSeverityValues) {
|
||||
for(const level of CompilerErrorSeverityValues) {
|
||||
if(errorSeverityName[level].startsWith(name)) {
|
||||
return level;
|
||||
}
|
||||
47
developer/src/common/web/utils/src/index.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
export { validateMITLicense } from './utils/validate-mit-license.js';
|
||||
export { KeymanSentry, SentryNodeOptions } from './utils/KeymanSentry.js';
|
||||
export { getOption, loadOptions, clearOptions } from './utils/options.js';
|
||||
export { escapeMarkdownChar } from './utils/markdown.js';
|
||||
export { KeymanUrls } from './utils/keyman-urls.js';
|
||||
|
||||
export * as KPJ from './types/kpj/kpj-file.js';
|
||||
export { KPJFileReader } from './types/kpj/kpj-file-reader.js';
|
||||
export { KeymanDeveloperProject, KeymanDeveloperProjectFile, KeymanDeveloperProjectType, } from './types/kpj/keyman-developer-project.js';
|
||||
export { isValidEmail } from './is-valid-email.js';
|
||||
|
||||
export * as KpsFile from './types/kps/kps-file.js';
|
||||
|
||||
export { default as KvksFileReader } from './types/kvks/kvks-file-reader.js';
|
||||
export { default as KvksFileWriter } from './types/kvks/kvks-file-writer.js';
|
||||
export * as KvksFile from './types/kvks/kvks-file.js';
|
||||
|
||||
export { TouchLayoutFileReader } from './types/keyman-touch-layout/keyman-touch-layout-file-reader.js';
|
||||
export { TouchLayoutFileWriter, TouchLayoutFileWriterOptions } from './types/keyman-touch-layout/keyman-touch-layout-file-writer.js';
|
||||
|
||||
export { default as KMXBuilder } from './types/kmx/kmx-builder.js';
|
||||
export { default as KMXPlusBuilder} from './types/kmx/kmx-plus-builder/kmx-plus-builder.js';
|
||||
|
||||
export * as LDMLKeyboard from './types/ldml-keyboard/ldml-keyboard-xml.js';
|
||||
export { LDMLKeyboardTestDataXMLSourceFile } from './types/ldml-keyboard/ldml-keyboard-testdata-xml.js';
|
||||
export { LDMLKeyboardXMLSourceFileReader, LDMLKeyboardXMLSourceFileReaderOptions } from './types/ldml-keyboard/ldml-keyboard-xml-reader.js';
|
||||
|
||||
export { defaultCompilerOptions, CompilerBaseOptions, CompilerCallbacks, CompilerOptions, CompilerEvent, CompilerErrorNamespace,
|
||||
CompilerErrorSeverity, CompilerPathCallbacks, CompilerFileSystemCallbacks, CompilerCallbackOptions,
|
||||
CompilerError, CompilerMessageSpec, CompilerMessageSpecWithException, compilerErrorSeverity, CompilerErrorMask, CompilerFileCallbacks, compilerErrorSeverityName,
|
||||
compilerErrorFormatCode, CompilerMessageDef,
|
||||
compilerLogLevelToSeverity, CompilerLogLevel, compilerEventFormat, ALL_COMPILER_LOG_LEVELS,
|
||||
ALL_COMPILER_LOG_FORMATS, CompilerLogFormat,
|
||||
CompilerMessageOverride,
|
||||
CompilerMessageOverrideMap,
|
||||
|
||||
KeymanCompilerArtifact,
|
||||
KeymanCompilerArtifactOptional,
|
||||
KeymanCompilerArtifacts,
|
||||
KeymanCompilerResult,
|
||||
KeymanCompiler
|
||||
|
||||
} from './compiler-interfaces.js';
|
||||
|
||||
export { CommonTypesMessages } from './common-events.js';
|
||||
|
||||
export * as xml2js from './deps/xml2js/xml2js.js';
|
||||
2
developer/src/common/web/utils/src/restructure.d.ts
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// TODO: consider defining more types?
|
||||
declare module 'restructure';
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { TouchLayoutFile } from "./keyman-touch-layout-file.js";
|
||||
import SchemaValidators from '../schema-validators.js';
|
||||
import { TouchLayout } from "@keymanapp/common-types";
|
||||
import TouchLayoutFile = TouchLayout.TouchLayoutFile;
|
||||
import { SchemaValidators } from '@keymanapp/common-types';
|
||||
|
||||
export class TouchLayoutFileReader {
|
||||
public read(source: Uint8Array): TouchLayoutFile {
|
||||
|
|
@ -22,7 +23,7 @@ export class TouchLayoutFileReader {
|
|||
// `row.id` should be number, but may have been stringified; we use
|
||||
// presence of `key` property to recognise this as a `TouchLayoutRow`.
|
||||
if(this.key && key == 'id' && typeof value == 'string') {
|
||||
let newValue = parseInt(value, 10);
|
||||
const newValue = parseInt(value, 10);
|
||||
/* c8 ignore next 3 */
|
||||
if(isNaN(newValue)) {
|
||||
throw new TypeError(`Invalid row.id: "${value}"`);
|
||||
|
|
@ -39,7 +40,7 @@ export class TouchLayoutFileReader {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
let newValue = parseInt(value, 10);
|
||||
const newValue = parseInt(value, 10);
|
||||
/* c8 ignore next 3 */
|
||||
if(isNaN(newValue)) {
|
||||
throw new TypeError(`Invalid [sub]key.${key}: "${value}"`);
|
||||
|
|
@ -67,10 +68,10 @@ export class TouchLayoutFileReader {
|
|||
}
|
||||
|
||||
public validate(source: TouchLayoutFile): void {
|
||||
if(!SchemaValidators.touchLayoutClean(source))
|
||||
if(!SchemaValidators.default.touchLayoutClean(source))
|
||||
/* c8 ignore next 3 */
|
||||
{
|
||||
throw new Error(JSON.stringify((<any>SchemaValidators.touchLayoutClean).errors));
|
||||
throw new Error(JSON.stringify((<any>SchemaValidators.default.touchLayoutClean).errors));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
import { TouchLayoutFile, TouchLayoutPlatform, TouchLayoutKey, TouchLayoutSubKey } from "./keyman-touch-layout-file.js";
|
||||
import { TouchLayout } from "@keymanapp/common-types";
|
||||
import TouchLayoutFile = TouchLayout.TouchLayoutFile;
|
||||
import TouchLayoutPlatform = TouchLayout.TouchLayoutPlatform;;
|
||||
import TouchLayoutKey = TouchLayout.TouchLayoutKey;
|
||||
import TouchLayoutSubKey = TouchLayout.TouchLayoutSubKey;
|
||||
|
||||
export interface TouchLayoutFileWriterOptions {
|
||||
formatted?: boolean;
|
||||
|
|
@ -87,24 +91,24 @@ export class TouchLayoutFileWriter {
|
|||
// displayUnderlying is always written out by kmcomp, so we do the same for kmc:
|
||||
platform.displayUnderlying = !!platform.displayUnderlying;
|
||||
|
||||
for(let layer of platform.layer) {
|
||||
for(let row of layer.row) {
|
||||
for(const layer of platform.layer) {
|
||||
for(const row of layer.row) {
|
||||
// this matches the old spec for touch layout files
|
||||
(row.id as any) = row.id.toString();
|
||||
for(let key of row.key) {
|
||||
for(const key of row.key) {
|
||||
fixupKey(key);
|
||||
if(key.sk) {
|
||||
for(let sk of key.sk) {
|
||||
for(const sk of key.sk) {
|
||||
fixupKey(sk);
|
||||
}
|
||||
}
|
||||
if(key.multitap) {
|
||||
for(let sk of key.multitap) {
|
||||
for(const sk of key.multitap) {
|
||||
fixupKey(sk);
|
||||
}
|
||||
}
|
||||
if(key.flick) {
|
||||
for(let id of Object.keys(key.flick)) {
|
||||
for(const id of Object.keys(key.flick)) {
|
||||
fixupKey((key.flick as any)[id] as TouchLayoutSubKey);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,18 @@
|
|||
import { KMXPlus, KMX } from '@keymanapp/common-types';
|
||||
import * as r from 'restructure';
|
||||
import { KMXFile, GROUP, KEY, STORE, BUILDER_COMP_KEYBOARD, BUILDER_COMP_KEYBOARD_KMXPLUSINFO, BUILDER_COMP_STORE, BUILDER_COMP_GROUP, BUILDER_COMP_KEY } from './kmx.js';
|
||||
import { KMXPlusFile } from './kmx-plus.js';
|
||||
import KMXPlusBuilder from './kmx-plus-builder/kmx-plus-builder.js';
|
||||
|
||||
import KMXPlusFile = KMXPlus.KMXPlusFile;
|
||||
import KMXFile = KMX.KMXFile;
|
||||
import GROUP = KMX.GROUP;
|
||||
import KEY = KMX.KEY;
|
||||
import STORE = KMX.STORE;
|
||||
import BUILDER_COMP_KEYBOARD = KMX.BUILDER_COMP_KEYBOARD;
|
||||
import BUILDER_COMP_KEYBOARD_KMXPLUSINFO = KMX.BUILDER_COMP_KEYBOARD_KMXPLUSINFO;
|
||||
import BUILDER_COMP_STORE = KMX.BUILDER_COMP_STORE;
|
||||
import BUILDER_COMP_GROUP = KMX.BUILDER_COMP_GROUP;
|
||||
import BUILDER_COMP_KEY = KMX.BUILDER_COMP_KEY;
|
||||
|
||||
export default class KMXBuilder {
|
||||
file: KMXFile;
|
||||
base_keyboard: number = 0;
|
||||
|
|
@ -69,8 +79,8 @@ export default class KMXBuilder {
|
|||
this.comp_header.dpStoreArray = this.comp_header.cxStoreArray ? size : 0;
|
||||
let storeBase = size;
|
||||
size += this.file.keyboard.stores.length * KMXFile.COMP_STORE_SIZE;
|
||||
for(let store of this.file.keyboard.stores) {
|
||||
let comp_store: BUILDER_COMP_STORE = {
|
||||
for(const store of this.file.keyboard.stores) {
|
||||
const comp_store: BUILDER_COMP_STORE = {
|
||||
dwSystemID: store.dwSystemID,
|
||||
dpName: 0,
|
||||
dpString: 0
|
||||
|
|
@ -90,8 +100,8 @@ export default class KMXBuilder {
|
|||
this.comp_header.dpGroupArray = this.comp_header.cxGroupArray ? size : 0;
|
||||
let groupBase = size;
|
||||
size += this.file.keyboard.groups.length * KMXFile.COMP_GROUP_SIZE;
|
||||
for(let group of this.file.keyboard.groups) {
|
||||
let comp_group: BUILDER_COMP_GROUP = {
|
||||
for(const group of this.file.keyboard.groups) {
|
||||
const comp_group: BUILDER_COMP_GROUP = {
|
||||
dpName: 0,
|
||||
dpKeyArray: 0,
|
||||
dpMatch: 0,
|
||||
|
|
@ -100,7 +110,7 @@ export default class KMXBuilder {
|
|||
fUsingKeys: group.fUsingKeys ? 1 : 0
|
||||
};
|
||||
|
||||
let comp_keys: {base: number, key: KEY, obj: BUILDER_COMP_KEY}[] = [];
|
||||
const comp_keys: {base: number, key: KEY, obj: BUILDER_COMP_KEY}[] = [];
|
||||
|
||||
this.comp_groups.push({base: groupBase, group: group, obj: comp_group, keys: comp_keys});
|
||||
|
||||
|
|
@ -116,8 +126,8 @@ export default class KMXBuilder {
|
|||
|
||||
let keyBase = size;
|
||||
size += group.keys.length * KMXFile.COMP_KEY_SIZE;
|
||||
for(let key of group.keys) {
|
||||
let comp_key: BUILDER_COMP_KEY = {
|
||||
for(const key of group.keys) {
|
||||
const comp_key: BUILDER_COMP_KEY = {
|
||||
Key: key.Key,
|
||||
_padding: 0,
|
||||
Line: key.Line,
|
||||
|
|
@ -164,11 +174,11 @@ export default class KMXBuilder {
|
|||
if(requireString && !str.length) {
|
||||
// Just write zero terminator, as r.String for a zero-length string
|
||||
// seems to fail.
|
||||
let sbuf = r.uint16le;
|
||||
const sbuf = r.uint16le;
|
||||
file.set(sbuf.toBuffer(0), pos);
|
||||
}
|
||||
else if(pos && str.length) {
|
||||
let sbuf = new r.String(null, 'utf16le'); // null-terminated string
|
||||
const sbuf = new r.String(null, 'utf16le'); // null-terminated string
|
||||
file.set(sbuf.toBuffer(str), pos);
|
||||
}
|
||||
}
|
||||
|
|
@ -176,7 +186,7 @@ export default class KMXBuilder {
|
|||
compile(): Uint8Array {
|
||||
const fileSize = this.build();
|
||||
|
||||
let file: Uint8Array = new Uint8Array(fileSize);
|
||||
const file: Uint8Array = new Uint8Array(fileSize);
|
||||
|
||||
// Write headers
|
||||
|
||||
|
|
@ -190,7 +200,7 @@ export default class KMXBuilder {
|
|||
|
||||
// Write store array and data
|
||||
|
||||
for(let store of this.comp_stores) {
|
||||
for(const store of this.comp_stores) {
|
||||
file.set(this.file.COMP_STORE.toBuffer(store.obj), store.base);
|
||||
if(this.writeDebug) {
|
||||
this.setString(file, store.obj.dpName, store.store.dpName);
|
||||
|
|
@ -200,7 +210,7 @@ export default class KMXBuilder {
|
|||
|
||||
// Write group array and data
|
||||
|
||||
for(let group of this.comp_groups) {
|
||||
for(const group of this.comp_groups) {
|
||||
file.set(this.file.COMP_GROUP.toBuffer(group.obj), group.base);
|
||||
if(this.writeDebug) {
|
||||
this.setString(file, group.obj.dpName, group.group.dpName);
|
||||
|
|
@ -208,7 +218,7 @@ export default class KMXBuilder {
|
|||
this.setString(file, group.obj.dpMatch, group.group.dpMatch);
|
||||
this.setString(file, group.obj.dpNoMatch, group.group.dpNoMatch);
|
||||
|
||||
for(let key of group.keys) {
|
||||
for(const key of group.keys) {
|
||||
file.set(this.file.COMP_KEY.toBuffer(key.obj), key.base);
|
||||
// for back-compat reasons, these are never NULL strings
|
||||
this.setString(file, key.obj.dpContext, key.key.dpContext, true);
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
import { constants } from '@keymanapp/ldml-keyboard-constants';
|
||||
import { KMXPlusData } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js";
|
||||
import { BUILDER_SECTION } from './builder-section.js';
|
||||
|
||||
import KMXPlusData = KMXPlus.KMXPlusData;
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* disp section
|
||||
------------------------------------------------------------------ */
|
||||
|
|
@ -27,7 +29,7 @@ export function build_disp(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS): BUILD
|
|||
return null;
|
||||
}
|
||||
|
||||
let disp: BUILDER_DISP = {
|
||||
const disp: BUILDER_DISP = {
|
||||
ident: constants.hex_section_id(constants.section.disp),
|
||||
size: constants.length_disp + constants.length_disp_item * kmxplus.disp.disps.length,
|
||||
_offset: 0,
|
||||
|
|
@ -36,7 +38,7 @@ export function build_disp(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS): BUILD
|
|||
items: []
|
||||
};
|
||||
|
||||
for(let item of kmxplus.disp.disps) {
|
||||
for(const item of kmxplus.disp.disps) {
|
||||
disp.items.push({
|
||||
to: build_strs_index(sect_strs, item.to),
|
||||
id: build_strs_index(sect_strs, item.id),
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import { constants } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { ElementString } from "../element-string.js";
|
||||
import { Elem } from "../kmx-plus.js";
|
||||
import { KMXPlus, ElementString } from "@keymanapp/common-types";
|
||||
import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js";
|
||||
import { BUILDER_SECTION, BUILDER_U32CHAR } from "./builder-section.js";
|
||||
import { build_uset_index, BUILDER_USET, BUILDER_USET_REF } from "./build-uset.js";
|
||||
|
||||
import Elem = KMXPlus.Elem;
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* elem section
|
||||
------------------------------------------------------------------ */
|
||||
|
|
@ -46,7 +47,7 @@ function binaryElemCompare(a: BUILDER_ELEM_STRING, b: BUILDER_ELEM_STRING): numb
|
|||
}
|
||||
|
||||
export function build_elem(source_elem: Elem, sect_strs: BUILDER_STRS, sect_uset: BUILDER_USET): BUILDER_ELEM {
|
||||
let result: BUILDER_ELEM = {
|
||||
const result: BUILDER_ELEM = {
|
||||
ident: constants.hex_section_id(constants.section.elem),
|
||||
size: 0, // finalized below
|
||||
_offset: 0,
|
||||
|
|
@ -55,7 +56,7 @@ export function build_elem(source_elem: Elem, sect_strs: BUILDER_STRS, sect_uset
|
|||
};
|
||||
|
||||
result.strings = source_elem.strings.map(item => {
|
||||
let res: BUILDER_ELEM_STRING = {
|
||||
const res: BUILDER_ELEM_STRING = {
|
||||
offset: 0, // finalized below
|
||||
length: item.length,
|
||||
items: [],
|
||||
|
|
@ -87,7 +88,7 @@ export function build_elem(source_elem: Elem, sect_strs: BUILDER_STRS, sect_uset
|
|||
/* Calculate offsets and total size */
|
||||
|
||||
let offset = constants.length_elem + constants.length_elem_item * result.count;
|
||||
for(let item of result.strings) {
|
||||
for(const item of result.strings) {
|
||||
if (item.length === 0) {
|
||||
// no length gets a zero offset
|
||||
item.offset = 0;
|
||||
|
|
@ -1,10 +1,14 @@
|
|||
|
||||
import { constants } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { KeysFlick, KMXPlusData, StrsItem } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js";
|
||||
import { build_list_index, BUILDER_LIST, BUILDER_LIST_REF } from "./build-list.js";
|
||||
import { BUILDER_SECTION, BUILDER_U32CHAR } from "./builder-section.js";
|
||||
|
||||
import KeysFlick = KMXPlus.KeysFlick;
|
||||
import KMXPlusData = KMXPlus.KMXPlusData;
|
||||
import StrsItem = KMXPlus.StrsItem;
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* keys section
|
||||
------------------------------------------------------------------ */
|
||||
|
|
@ -71,7 +75,7 @@ export function build_keys(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS, sect_l
|
|||
return null;
|
||||
}
|
||||
|
||||
let keys: BUILDER_KEYS = {
|
||||
const keys: BUILDER_KEYS = {
|
||||
ident: constants.hex_section_id(constants.section.keys),
|
||||
size: 0,
|
||||
keyCount: kmxplus.keys.keys.length,
|
||||
|
|
@ -89,7 +93,7 @@ export function build_keys(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS, sect_l
|
|||
|
||||
// Note that per the Keys class and spec, there is always a flicks=0 meaning 'no flicks'
|
||||
keys.flicks = kmxplus.keys.flicks.map((flicks) => {
|
||||
let result : BUILDER_KEYS_FLICKS = {
|
||||
const result : BUILDER_KEYS_FLICKS = {
|
||||
count: flicks.flicks.length,
|
||||
flick: keys.flick.length, // index of first flick
|
||||
id: build_strs_index(sect_strs, flicks.id),
|
||||
|
|
@ -113,7 +117,7 @@ export function build_keys(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS, sect_l
|
|||
|
||||
// now, keys
|
||||
keys.keys = kmxplus.keys.keys.map((key) => {
|
||||
let result : BUILDER_KEYS_KEY = {
|
||||
const result : BUILDER_KEYS_KEY = {
|
||||
to: build_strs_index(sect_strs, key.to),
|
||||
flags: key.flags,
|
||||
id: build_strs_index(sect_strs, key.id),
|
||||
|
|
@ -136,7 +140,7 @@ export function build_keys(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS, sect_l
|
|||
|
||||
// finally, kmap
|
||||
keys.kmap = kmxplus.keys.kmap.map(({vkey, mod, key}) => {
|
||||
let result : BUILDER_KEYS_KMAP = {
|
||||
const result : BUILDER_KEYS_KMAP = {
|
||||
vkey,
|
||||
mod,
|
||||
key: keys.keys.findIndex(k => k._id === key),
|
||||
|
|
@ -160,7 +164,7 @@ export function build_keys(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS, sect_l
|
|||
return rc;
|
||||
});
|
||||
|
||||
let offset = constants.length_keys +
|
||||
const offset = constants.length_keys +
|
||||
(constants.length_keys_key * keys.keyCount) +
|
||||
(constants.length_keys_flick_element * keys.flickCount) +
|
||||
(constants.length_keys_flick_list * keys.flicksCount) +
|
||||
|
|
@ -1,10 +1,15 @@
|
|||
|
||||
import { constants } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { KMXPlusData, LayrEntry, LayrRow, StrsItem } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js";
|
||||
import { BUILDER_LIST } from "./build-list.js";
|
||||
import { BUILDER_SECTION } from "./builder-section.js";
|
||||
|
||||
import KMXPlusData = KMXPlus.KMXPlusData;
|
||||
import LayrEntry = KMXPlus.LayrEntry;
|
||||
import LayrRow = KMXPlus.LayrRow;
|
||||
import StrsItem = KMXPlus.StrsItem;
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* layr section -
|
||||
------------------------------------------------------------------ */
|
||||
|
|
@ -66,7 +71,7 @@ export function build_layr(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS, sect_l
|
|||
return null; // if there aren't any layers at all (which should be an invalid keyboard)
|
||||
}
|
||||
|
||||
let layr: BUILDER_LAYR = {
|
||||
const layr: BUILDER_LAYR = {
|
||||
ident: constants.hex_section_id(constants.section.layr),
|
||||
size: constants.length_layr,
|
||||
_offset: 0,
|
||||
|
|
@ -145,7 +150,7 @@ export function build_layr(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS, sect_l
|
|||
layr.rowCount = layr.rows.length;
|
||||
layr.keyCount = layr.keys.length;
|
||||
|
||||
let offset = constants.length_layr +
|
||||
const offset = constants.length_layr +
|
||||
(constants.length_layr_list * layr.listCount) +
|
||||
(constants.length_layr_entry * layr.layerCount) +
|
||||
(constants.length_layr_row * layr.rowCount) +
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
import { constants } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { List, ListItem } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js";
|
||||
import { BUILDER_SECTION } from "./builder-section.js";
|
||||
|
||||
import List = KMXPlus.List;
|
||||
import ListItem = KMXPlus.ListItem;
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* list section
|
||||
------------------------------------------------------------------ */
|
||||
|
|
@ -40,7 +43,7 @@ export function build_list(source_list: List, sect_strs: BUILDER_STRS): BUILDER_
|
|||
return null;
|
||||
}
|
||||
|
||||
let result: BUILDER_LIST = {
|
||||
const result: BUILDER_LIST = {
|
||||
ident: constants.hex_section_id(constants.section.list),
|
||||
size: 0,
|
||||
_offset: 0,
|
||||
|
|
@ -51,13 +54,13 @@ export function build_list(source_list: List, sect_strs: BUILDER_STRS): BUILDER_
|
|||
};
|
||||
|
||||
result.lists = source_list.lists.map(array => {
|
||||
let list : BUILDER_LIST_LIST = {
|
||||
const list : BUILDER_LIST_LIST = {
|
||||
index: result.indices.length, // the next indexcount
|
||||
count: array.length,
|
||||
_value: array
|
||||
};
|
||||
array.forEach((i) => {
|
||||
let index : BUILDER_LIST_INDEX = {
|
||||
const index : BUILDER_LIST_INDEX = {
|
||||
// Get the final string index
|
||||
str: build_strs_index(sect_strs, i.value),
|
||||
_value: i.value.value, // unwrap the actual string value
|
||||
|
|
@ -71,7 +74,7 @@ export function build_list(source_list: List, sect_strs: BUILDER_STRS): BUILDER_
|
|||
// Sort the lists.
|
||||
result.lists.sort((a,b) => a._value.compareTo(b._value));
|
||||
|
||||
let offset = constants.length_list +
|
||||
const offset = constants.length_list +
|
||||
(constants.length_list_item * result.listCount) +
|
||||
(constants.length_list_index * result.indexCount);
|
||||
result.size = offset;
|
||||
|
|
@ -86,14 +89,14 @@ export function build_list(source_list: List, sect_strs: BUILDER_STRS): BUILDER_
|
|||
* @returns
|
||||
*/
|
||||
export function build_list_index(sect_list: BUILDER_LIST, value: ListItem) : BUILDER_LIST_REF {
|
||||
if (!value) {
|
||||
if (!value) {
|
||||
return 0; // empty list
|
||||
}
|
||||
if(!(value instanceof ListItem)) {
|
||||
throw new Error('unexpected value '+ value);
|
||||
}
|
||||
|
||||
let result = sect_list.lists.findIndex(v => v._value === value);
|
||||
const result = sect_list.lists.findIndex(v => v._value === value);
|
||||
if(result < 0) {
|
||||
throw new Error('unexpectedly missing ListItem ' + value); // TODO-LDML: it's an array of strs
|
||||
}
|
||||
|
|
@ -4,10 +4,12 @@
|
|||
------------------------------------------------------------------ */
|
||||
|
||||
import { constants } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { KMXPlusData } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js";
|
||||
import { BUILDER_SECTION } from "./builder-section.js";
|
||||
|
||||
import KMXPlusData = KMXPlus.KMXPlusData;
|
||||
|
||||
/**
|
||||
* Builder for the 'loca' section
|
||||
*/
|
||||
|
|
@ -17,7 +19,7 @@ export interface BUILDER_LOCA extends BUILDER_SECTION {
|
|||
};
|
||||
|
||||
export function build_loca(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS): BUILDER_LOCA {
|
||||
let loca: BUILDER_LOCA = {
|
||||
const loca: BUILDER_LOCA = {
|
||||
ident: constants.hex_section_id(constants.section.loca),
|
||||
size: constants.length_loca + constants.length_loca_item * kmxplus.loca.locales.length,
|
||||
_offset: 0,
|
||||
|
|
@ -25,7 +27,7 @@ export function build_loca(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS): BUILD
|
|||
items: []
|
||||
};
|
||||
|
||||
for(let item of kmxplus.loca.locales) {
|
||||
for(const item of kmxplus.loca.locales) {
|
||||
loca.items.push(build_strs_index(sect_strs, item));
|
||||
}
|
||||
|
||||
|
|
@ -4,10 +4,12 @@
|
|||
------------------------------------------------------------------ */
|
||||
|
||||
import { constants } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { KMXPlusData } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js";
|
||||
import { BUILDER_SECTION } from "./builder-section.js";
|
||||
|
||||
import KMXPlusData = KMXPlus.KMXPlusData;
|
||||
|
||||
/**
|
||||
* Builder for the 'meta' section
|
||||
*/
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
import { constants } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { Strs, StrsItem } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { BUILDER_SECTION } from "./builder-section.js";
|
||||
|
||||
import Strs = KMXPlus.Strs;
|
||||
import StrsItem = KMXPlus.StrsItem;
|
||||
|
||||
/** reference from build_strs_index */
|
||||
export type BUILDER_STR_REF = number;
|
||||
|
||||
|
|
@ -26,7 +29,7 @@ export interface BUILDER_STRS extends BUILDER_SECTION {
|
|||
};
|
||||
|
||||
export function build_strs(source_strs: Strs): BUILDER_STRS {
|
||||
let result: BUILDER_STRS = {
|
||||
const result: BUILDER_STRS = {
|
||||
ident: constants.hex_section_id(constants.section.strs),
|
||||
size: 0, // finalized later
|
||||
_offset: 0,
|
||||
|
|
@ -39,7 +42,7 @@ export function build_strs(source_strs: Strs): BUILDER_STRS {
|
|||
|
||||
let offset = constants.length_strs + constants.length_strs_item * result.count;
|
||||
// TODO: consider padding
|
||||
for(let item of result.items) {
|
||||
for(const item of result.items) {
|
||||
item.offset = offset;
|
||||
offset += item.length * 2 + 2; /* UTF-16 code units + sizeof null terminator */
|
||||
}
|
||||
|
|
@ -64,7 +67,7 @@ export function build_strs_index(sect_strs: BUILDER_STRS, value: StrsItem) : BUI
|
|||
return <BUILDER_STR_REF>value.char;
|
||||
}
|
||||
|
||||
let result = sect_strs.items.findIndex(v => v._value === value.value);
|
||||
const result = sect_strs.items.findIndex(v => v._value === value.value);
|
||||
if(result < 0) {
|
||||
throw new Error('unexpectedly missing StrsItem '+value.value);
|
||||
}
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
|
||||
import { constants } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { Bksp, Tran } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { BUILDER_ELEM, BUILDER_ELEM_REF, build_elem_index } from "./build-elem.js";
|
||||
import { BUILDER_STRS, BUILDER_STR_REF, build_strs_index } from "./build-strs.js";
|
||||
import { BUILDER_SECTION } from "./builder-section.js";
|
||||
|
||||
import Bksp = KMXPlus.Bksp;
|
||||
import Tran = KMXPlus.Tran;
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* tran section
|
||||
------------------------------------------------------------------ */
|
||||
|
|
@ -44,7 +47,7 @@ export function build_tran(source_tran: Tran | Bksp, sect_strs: BUILDER_STRS, se
|
|||
return null;
|
||||
}
|
||||
|
||||
let tran: BUILDER_TRAN = {
|
||||
const tran: BUILDER_TRAN = {
|
||||
ident: constants.hex_section_id(source_tran.id),
|
||||
size: 0, // need to compute total transforms + reorders
|
||||
_offset: 0,
|
||||
|
|
@ -56,14 +59,14 @@ export function build_tran(source_tran: Tran | Bksp, sect_strs: BUILDER_STRS, se
|
|||
reorders: [],
|
||||
};
|
||||
|
||||
for (let group of source_tran.groups) {
|
||||
for (const group of source_tran.groups) {
|
||||
if (group.type === constants.tran_group_type_transform) {
|
||||
tran.groups.push({
|
||||
type: group.type,
|
||||
count: group.transforms.length,
|
||||
index: tran.transforms.length, // index of first item
|
||||
});
|
||||
for (let transform of group.transforms) {
|
||||
for (const transform of group.transforms) {
|
||||
tran.transforms.push({
|
||||
from: build_strs_index(sect_strs, transform.from),
|
||||
to: build_strs_index(sect_strs, transform.to),
|
||||
|
|
@ -77,7 +80,7 @@ export function build_tran(source_tran: Tran | Bksp, sect_strs: BUILDER_STRS, se
|
|||
count: group.reorders.length,
|
||||
index: tran.reorders.length, // index of first item
|
||||
});
|
||||
for (let reorder of group.reorders) {
|
||||
for (const reorder of group.reorders) {
|
||||
tran.reorders.push({
|
||||
elements: build_elem_index(sect_elem, reorder.elements),
|
||||
before: build_elem_index(sect_elem, reorder.before),
|
||||
|
|
@ -1,8 +1,12 @@
|
|||
import { constants } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { KMXPlusData, StrsItem, UsetItem } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js";
|
||||
import { BUILDER_SECTION, BUILDER_U32CHAR } from "./builder-section.js";
|
||||
|
||||
import KMXPlusData = KMXPlus.KMXPlusData;
|
||||
import StrsItem = KMXPlus.StrsItem;
|
||||
import UsetItem = KMXPlus.UsetItem;
|
||||
|
||||
/** reference from build_uset_index */
|
||||
export type BUILDER_USET_REF = number;
|
||||
|
||||
|
|
@ -80,7 +84,7 @@ export function build_uset_index(sect_uset: BUILDER_USET, value: UsetItem) {
|
|||
}
|
||||
}
|
||||
|
||||
let result = sect_uset.usets.findIndex(v => v._pattern.value === value.str.value);
|
||||
const result = sect_uset.usets.findIndex(v => v._pattern.value === value.str.value);
|
||||
if(result < 0) {
|
||||
throw new Error('unexpectedly missing UsetItem ' + value.uset.toString());
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import { constants } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { KMXPlusData } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js";
|
||||
import { BUILDER_SECTION } from "./builder-section.js";
|
||||
import { build_list_index, BUILDER_LIST, BUILDER_LIST_REF } from "./build-list.js";
|
||||
import { build_elem_index, BUILDER_ELEM, BUILDER_ELEM_REF } from "./build-elem.js";
|
||||
|
||||
import KMXPlusData = KMXPlus.KMXPlusData;
|
||||
|
||||
interface BUILDER_VARS_ITEM {
|
||||
type: number;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import * as r from 'restructure';
|
||||
import { KMXPlusFile } from "../kmx-plus.js";
|
||||
import { KMXPlus } from "@keymanapp/common-types";
|
||||
import { constants, SectionIdent } from '@keymanapp/ldml-keyboard-constants';
|
||||
import { BUILDER_SECTION } from './builder-section.js';
|
||||
import { BUILDER_SECT, build_sect } from './build-sect.js';
|
||||
|
|
@ -15,6 +15,8 @@ import { BUILDER_TRAN, build_tran } from './build-tran.js';
|
|||
import { BUILDER_USET, build_uset } from './build-uset.js';
|
||||
import { BUILDER_VARS, build_vars } from './build-vars.js';
|
||||
|
||||
import KMXPlusFile = KMXPlus.KMXPlusFile;
|
||||
|
||||
type BUILDER_BKSP = BUILDER_TRAN;
|
||||
// type BUILDER_FINL = BUILDER_TRAN;
|
||||
|
||||
|
|
@ -50,7 +52,7 @@ export default class KMXPlusBuilder {
|
|||
|
||||
public compile(): Uint8Array {
|
||||
const fileSize = this.build();
|
||||
let file: Uint8Array = new Uint8Array(fileSize);
|
||||
const file: Uint8Array = new Uint8Array(fileSize);
|
||||
|
||||
this.emitSection(file, this.file.COMP_PLUS_SECT, this.sect.sect);
|
||||
// Keep the rest of these in order.
|
||||
|
|
@ -155,13 +157,13 @@ export default class KMXPlusBuilder {
|
|||
}
|
||||
|
||||
private emitStrings(file: Uint8Array) {
|
||||
for(let item of this.sect.strs.items) {
|
||||
for(const item of this.sect.strs.items) {
|
||||
if(item._value === '') {
|
||||
// We have a special case for the zero-length string
|
||||
let sbuf = r.uint16le;
|
||||
const sbuf = r.uint16le;
|
||||
file.set(sbuf.toBuffer(0), item.offset + this.sect.strs._offset);
|
||||
} else {
|
||||
let sbuf = new r.String(null, 'utf16le');
|
||||
const sbuf = new r.String(null, 'utf16le');
|
||||
file.set(sbuf.toBuffer(item._value), item.offset + this.sect.strs._offset);
|
||||
}
|
||||
}
|
||||
|
|
@ -169,9 +171,9 @@ export default class KMXPlusBuilder {
|
|||
|
||||
private emitElements(file: Uint8Array) {
|
||||
if(this.sect.elem) {
|
||||
for(let str of this.sect.elem.strings) {
|
||||
for(const str of this.sect.elem.strings) {
|
||||
if(str.items.length > 0) {
|
||||
let COMP_PLUS_ELEM_ELEMENTS = new r.Array(this.file.COMP_PLUS_ELEM_ELEMENT, str.items.length);
|
||||
const COMP_PLUS_ELEM_ELEMENTS = new r.Array(this.file.COMP_PLUS_ELEM_ELEMENT, str.items.length);
|
||||
file.set(COMP_PLUS_ELEM_ELEMENTS.toBuffer(str.items), str.offset + this.sect.elem._offset);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
// Version 1.0 and 2.0 of Keyman Developer Project .kpj file
|
||||
//
|
||||
|
||||
import { KeymanFileTypes } from '../main.js';
|
||||
import { CompilerCallbacks } from '../util/compiler-interfaces.js';
|
||||
import { KeymanFileTypes } from '@keymanapp/common-types';
|
||||
import { CompilerCallbacks } from '../../compiler-interfaces.js';
|
||||
|
||||
export class KeymanDeveloperProject {
|
||||
options: KeymanDeveloperProjectOptions;
|
||||
|
|
@ -29,13 +29,13 @@ export class KeymanDeveloperProject {
|
|||
if(this.options.version != '2.0') {
|
||||
throw new Error('populateFiles can only be called on a v2.0 project');
|
||||
}
|
||||
let sourcePath = this.resolveProjectPath(this.options.sourcePath);
|
||||
const sourcePath = this.resolveProjectPath(this.options.sourcePath);
|
||||
if(!this.callbacks.fs.existsSync(sourcePath)) {
|
||||
return false;
|
||||
}
|
||||
let files = this.callbacks.fs.readdirSync(sourcePath);
|
||||
for(let filename of files) {
|
||||
let fullPath = this.callbacks.path.join(sourcePath, filename);
|
||||
const files = this.callbacks.fs.readdirSync(sourcePath);
|
||||
for(const filename of files) {
|
||||
const fullPath = this.callbacks.path.join(sourcePath, filename);
|
||||
if(KeymanFileTypes.filenameIs(filename, KeymanFileTypes.Source.LdmlKeyboard)) {
|
||||
try {
|
||||
const data = this.callbacks.loadFile(fullPath);
|
||||
|
|
@ -51,7 +51,7 @@ export class KeymanDeveloperProject {
|
|||
}
|
||||
}
|
||||
if(KeymanFileTypes.sourceTypeFromFilename(filename) !== null) {
|
||||
let file = new KeymanDeveloperProjectFile20(fullPath, this.callbacks);
|
||||
const file = new KeymanDeveloperProjectFile20(fullPath, this.callbacks);
|
||||
this.files.push(file);
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ export class KeymanDeveloperProject {
|
|||
|
||||
p = this.resolveProjectPath(p);
|
||||
|
||||
let f = file.filename.replace(new RegExp(`\\${sourceExt}$`, 'i'), targetExt);
|
||||
const f = file.filename.replace(new RegExp(`\\${sourceExt}$`, 'i'), targetExt);
|
||||
return this.callbacks.path.normalize(this.callbacks.path.join(p, f));
|
||||
}
|
||||
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
import * as xml2js from '../deps/xml2js/xml2js.js';
|
||||
import { xml2js } from '../../index.js';
|
||||
import { KPJFile, KPJFileProject } from './kpj-file.js';
|
||||
import { boxXmlArray } from '../util/util.js';
|
||||
import { util } from '@keymanapp/common-types';
|
||||
import { KeymanDeveloperProject, KeymanDeveloperProjectFile10, KeymanDeveloperProjectType } from './keyman-developer-project.js';
|
||||
import { CompilerCallbacks } from '../util/compiler-interfaces.js';
|
||||
import SchemaValidators from '../schema-validators.js';
|
||||
import { SchemaValidators } from '@keymanapp/common-types';
|
||||
import { CompilerCallbacks } from '../../compiler-interfaces.js';
|
||||
|
||||
export class KPJFileReader {
|
||||
constructor(private callbacks: CompilerCallbacks) {
|
||||
|
|
@ -29,7 +29,7 @@ export class KPJFileReader {
|
|||
});
|
||||
data = this.boxArrays(data);
|
||||
if(data.KeymanDeveloperProject?.Files?.File?.length) {
|
||||
for(let file of data.KeymanDeveloperProject?.Files?.File) {
|
||||
for(const file of data.KeymanDeveloperProject?.Files?.File) {
|
||||
// xml2js imports <Details/> as '' so we will just delete the empty string
|
||||
if(typeof file.Details == 'string') {
|
||||
delete file.Details;
|
||||
|
|
@ -40,11 +40,11 @@ export class KPJFileReader {
|
|||
}
|
||||
|
||||
public validate(source: KPJFile): void {
|
||||
if(!SchemaValidators.kpj(source)) {
|
||||
if(!SchemaValidators.kpj90(source)) {
|
||||
if(!SchemaValidators.default.kpj(source)) {
|
||||
if(!SchemaValidators.default.kpj90(source)) {
|
||||
// If the legacy schema also does not validate, then we will only report
|
||||
// the errors against the modern schema
|
||||
throw new Error(JSON.stringify((<any>SchemaValidators.kpj).errors));
|
||||
throw new Error(JSON.stringify((<any>SchemaValidators.default.kpj).errors));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,8 +60,8 @@ export class KPJFileReader {
|
|||
// NOTE: at this point, the xml should have been validated
|
||||
// and matched the schema result so we can assume the source
|
||||
// is a valid shape
|
||||
let project = source.KeymanDeveloperProject;
|
||||
let result: KeymanDeveloperProject = new KeymanDeveloperProject(projectFilename, project.Options?.Version || "1.0", this.callbacks);
|
||||
const project = source.KeymanDeveloperProject;
|
||||
const result: KeymanDeveloperProject = new KeymanDeveloperProject(projectFilename, project.Options?.Version || "1.0", this.callbacks);
|
||||
if(result.options.version == '2.0') {
|
||||
result.options.buildPath = (project.Options?.BuildPath || result.options.buildPath).replace(/\\/g, '/');
|
||||
result.options.sourcePath = (project.Options?.SourcePath || result.options.sourcePath).replace(/\\/g, '/');
|
||||
|
|
@ -88,9 +88,9 @@ export class KPJFileReader {
|
|||
}
|
||||
|
||||
private transformFilesVersion10(project: KPJFileProject, result: KeymanDeveloperProject) {
|
||||
let ids: { [id: string]: KeymanDeveloperProjectFile10; } = {};
|
||||
for (let sourceFile of project.Files?.File) {
|
||||
let file: KeymanDeveloperProjectFile10 = new KeymanDeveloperProjectFile10(
|
||||
const ids: { [id: string]: KeymanDeveloperProjectFile10; } = {};
|
||||
for (const sourceFile of project.Files?.File) {
|
||||
const file: KeymanDeveloperProjectFile10 = new KeymanDeveloperProjectFile10(
|
||||
sourceFile.ID || '',
|
||||
(sourceFile.Filepath || '').replace(/\\/g, '/'),
|
||||
sourceFile.FileVersion || '',
|
||||
|
|
@ -123,7 +123,7 @@ export class KPJFileReader {
|
|||
if(!source.KeymanDeveloperProject.Files || typeof source.KeymanDeveloperProject.Files == 'string') {
|
||||
source.KeymanDeveloperProject.Files = {File:[]};
|
||||
}
|
||||
boxXmlArray(source.KeymanDeveloperProject.Files, 'File');
|
||||
util.boxXmlArray(source.KeymanDeveloperProject.Files, 'File');
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,19 @@
|
|||
import * as xml2js from '../deps/xml2js/xml2js.js';
|
||||
import { SchemaValidators as SV, KvkFile, util, Constants } from '@keymanapp/common-types';
|
||||
import { xml2js } from '../../index.js'
|
||||
import KVKSourceFile from './kvks-file.js';
|
||||
import { boxXmlArray } from '../util/util.js';
|
||||
import { DEFAULT_KVK_FONT, VisualKeyboard, VisualKeyboardHeaderFlags, VisualKeyboardKey, VisualKeyboardKeyFlags, VisualKeyboardLegalShiftStates, VisualKeyboardShiftState } from './visual-keyboard.js';
|
||||
import { USVirtualKeyCodes } from '../consts/virtual-key-constants.js';
|
||||
import { BUILDER_KVK_HEADER_VERSION, KVK_HEADER_IDENTIFIER_BYTES } from './kvk-file.js';
|
||||
import SchemaValidators from '../schema-validators.js';
|
||||
const SchemaValidators = SV.default;
|
||||
import boxXmlArray = util.boxXmlArray;
|
||||
import USVirtualKeyCodes = Constants.USVirtualKeyCodes;
|
||||
import { VisualKeyboard as VK } from '@keymanapp/common-types';
|
||||
import DEFAULT_KVK_FONT = VK.DEFAULT_KVK_FONT;
|
||||
import VisualKeyboard = VK.VisualKeyboard;
|
||||
import VisualKeyboardHeaderFlags = VK.VisualKeyboardHeaderFlags;
|
||||
import VisualKeyboardKey = VK.VisualKeyboardKey;
|
||||
import VisualKeyboardKeyFlags = VK.VisualKeyboardKeyFlags;
|
||||
import VisualKeyboardLegalShiftStates = VK.VisualKeyboardLegalShiftStates;
|
||||
import VisualKeyboardShiftState = VK.VisualKeyboardShiftState;
|
||||
import BUILDER_KVK_HEADER_VERSION = KvkFile.BUILDER_KVK_HEADER_VERSION;
|
||||
import KVK_HEADER_IDENTIFIER_BYTES = KvkFile.KVK_HEADER_IDENTIFIER_BYTES;
|
||||
|
||||
|
||||
export default class KVKSFileReader {
|
||||
|
|
@ -69,9 +78,9 @@ export default class KVKSFileReader {
|
|||
}
|
||||
}
|
||||
|
||||
for(let key of Object.keys(source)) {
|
||||
for(const key of Object.keys(source)) {
|
||||
if(Array.isArray(source[key])) {
|
||||
for(let item of source[key]) {
|
||||
for(const item of source[key]) {
|
||||
if(typeof(item) === 'object') {
|
||||
this.cleanupUnderscore(key, item);
|
||||
}
|
||||
|
|
@ -92,7 +101,7 @@ export default class KVKSFileReader {
|
|||
// NOTE: at this point, the xml should have been validated
|
||||
// and matched the schema result so we can assume properties exist
|
||||
|
||||
let result: VisualKeyboard = {
|
||||
const result: VisualKeyboard = {
|
||||
header: {
|
||||
version: BUILDER_KVK_HEADER_VERSION,
|
||||
flags: 0,
|
||||
|
|
@ -117,22 +126,22 @@ export default class KVKSFileReader {
|
|||
result.header.flags |= VisualKeyboardHeaderFlags.kvkhUseUnderlying;
|
||||
}
|
||||
|
||||
for(let encoding of source.visualkeyboard.encoding) {
|
||||
let isUnicode = (encoding.$?.name == 'unicode'),
|
||||
for(const encoding of source.visualkeyboard.encoding) {
|
||||
const isUnicode = (encoding.$?.name == 'unicode'),
|
||||
font = isUnicode ? result.header.unicodeFont : result.header.ansiFont;
|
||||
font.name = encoding.$?.fontname ?? DEFAULT_KVK_FONT.name;
|
||||
font.size = parseInt(encoding.$?.fontsize ?? DEFAULT_KVK_FONT.size.toString(), 10);
|
||||
for(let layer of encoding.layer) {
|
||||
let shift = this.kvksShiftToKvkShift(layer.$?.shift);
|
||||
for(let sourceKey of layer.key) {
|
||||
let vkey = (USVirtualKeyCodes as any)[sourceKey.$?.vkey];
|
||||
for(const layer of encoding.layer) {
|
||||
const shift = this.kvksShiftToKvkShift(layer.$?.shift);
|
||||
for(const sourceKey of layer.key) {
|
||||
const vkey = (USVirtualKeyCodes as any)[sourceKey.$?.vkey];
|
||||
if(!vkey) {
|
||||
if(typeof invalidVkeys !== 'undefined') {
|
||||
invalidVkeys.push(sourceKey.$?.vkey);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
let key: VisualKeyboardKey = {
|
||||
const key: VisualKeyboardKey = {
|
||||
flags:
|
||||
(isUnicode ? VisualKeyboardKeyFlags.kvkkUnicode : 0) |
|
||||
(sourceKey.bitmap ? VisualKeyboardKeyFlags.kvkkBitmap : 0),
|
||||
|
|
@ -167,9 +176,9 @@ export default class KVKSFileReader {
|
|||
*/
|
||||
private boxArrays(source: KVKSourceFile) {
|
||||
boxXmlArray(source.visualkeyboard, 'encoding');
|
||||
for(let encoding of source.visualkeyboard.encoding) {
|
||||
for(const encoding of source.visualkeyboard.encoding) {
|
||||
boxXmlArray(encoding, 'layer');
|
||||
for(let layer of encoding.layer) {
|
||||
for(const layer of encoding.layer) {
|
||||
boxXmlArray(layer, 'key');
|
||||
}
|
||||
}
|
||||
|
|
@ -181,7 +190,7 @@ export default class KVKSFileReader {
|
|||
shift = shift.toUpperCase();
|
||||
|
||||
// TODO-LDML(lowpri): make a map of this?
|
||||
for(let state of VisualKeyboardLegalShiftStates) {
|
||||
for(const state of VisualKeyboardLegalShiftStates) {
|
||||
if(state.name == shift) {
|
||||
return state.shift;
|
||||
}
|
||||
|
|
@ -1,7 +1,13 @@
|
|||
import * as xml2js from '../deps/xml2js/xml2js.js';
|
||||
import { VisualKeyboard as VK, Constants } from '@keymanapp/common-types';
|
||||
import KVKSourceFile, { KVKSEncoding, KVKSFlags, KVKSKey, KVKSLayer } from './kvks-file.js';
|
||||
import { VisualKeyboard, VisualKeyboardHeaderFlags, VisualKeyboardKeyFlags, VisualKeyboardLegalShiftStates, VisualKeyboardShiftState } from './visual-keyboard.js';
|
||||
import { USVirtualKeyCodes } from '../consts/virtual-key-constants.js';
|
||||
import { xml2js } from '../../index.js';
|
||||
|
||||
import USVirtualKeyCodes = Constants.USVirtualKeyCodes;
|
||||
import VisualKeyboard = VK.VisualKeyboard;
|
||||
import VisualKeyboardHeaderFlags = VK.VisualKeyboardHeaderFlags;
|
||||
import VisualKeyboardKeyFlags = VK.VisualKeyboardKeyFlags;
|
||||
import VisualKeyboardLegalShiftStates = VK.VisualKeyboardLegalShiftStates;
|
||||
import VisualKeyboardShiftState = VK.VisualKeyboardShiftState;
|
||||
|
||||
export default class KVKSFileWriter {
|
||||
public write(vk: VisualKeyboard): string {
|
||||
|
|
@ -17,7 +23,7 @@ export default class KVKSFileWriter {
|
|||
}
|
||||
})
|
||||
|
||||
let flags: KVKSFlags = {};
|
||||
const flags: KVKSFlags = {};
|
||||
if(vk.header.flags & VisualKeyboardHeaderFlags.kvkhDisplayUnderlying) {
|
||||
flags.displayunderlying = '';
|
||||
}
|
||||
|
|
@ -33,7 +39,7 @@ export default class KVKSFileWriter {
|
|||
|
||||
|
||||
|
||||
let kvks: KVKSourceFile = {
|
||||
const kvks: KVKSourceFile = {
|
||||
visualkeyboard: {
|
||||
header: {
|
||||
version: '10.0',
|
||||
|
|
@ -46,9 +52,9 @@ export default class KVKSFileWriter {
|
|||
|
||||
if(vk.header.underlyingLayout) kvks.visualkeyboard.header.layout = vk.header.underlyingLayout;
|
||||
|
||||
let encodings: {ansi: {o: KVKSEncoding, l: {[name:string]:KVKSLayer}}, unicode: {o: KVKSEncoding, l: {[name:string]:KVKSLayer}}} = {ansi:null,unicode:null};
|
||||
const encodings: {ansi: {o: KVKSEncoding, l: {[name:string]:KVKSLayer}}, unicode: {o: KVKSEncoding, l: {[name:string]:KVKSLayer}}} = {ansi:null,unicode:null};
|
||||
|
||||
for(let key of vk.keys) {
|
||||
for(const key of vk.keys) {
|
||||
const encoding = key.flags & VisualKeyboardKeyFlags.kvkkUnicode ? 'unicode' : 'ansi';
|
||||
const shift = this.kvkShiftToKvksShift(key.shift);
|
||||
|
||||
|
|
@ -65,7 +71,7 @@ export default class KVKSFileWriter {
|
|||
};
|
||||
kvks.visualkeyboard.encoding.push(encodings[encoding].o);
|
||||
}
|
||||
let e = encodings[encoding];
|
||||
const e = encodings[encoding];
|
||||
if(!e.l[shift]) {
|
||||
e.l[shift] = {
|
||||
key: [],
|
||||
|
|
@ -73,11 +79,11 @@ export default class KVKSFileWriter {
|
|||
};
|
||||
e.o.layer.push(e.l[shift]);
|
||||
}
|
||||
let l = e.l[shift];
|
||||
const l = e.l[shift];
|
||||
|
||||
// TODO-LDML: map
|
||||
let vkeyName = '';
|
||||
for(let vkey of Object.keys(USVirtualKeyCodes)) {
|
||||
for(const vkey of Object.keys(USVirtualKeyCodes)) {
|
||||
if((USVirtualKeyCodes as any)[vkey] == key.vkey) {
|
||||
vkeyName = vkey;
|
||||
break;
|
||||
|
|
@ -88,7 +94,7 @@ export default class KVKSFileWriter {
|
|||
//TODO-LDML: warn
|
||||
continue;
|
||||
}
|
||||
let k: KVKSKey = {
|
||||
const k: KVKSKey = {
|
||||
$: {vkey: vkeyName},
|
||||
_: key.text,
|
||||
}
|
||||
|
|
@ -99,7 +105,7 @@ export default class KVKSFileWriter {
|
|||
l.key.push(k);
|
||||
}
|
||||
|
||||
let result = builder.buildObject(kvks);
|
||||
const result = builder.buildObject(kvks);
|
||||
return result; //Uint8Array.from(result);
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +117,7 @@ export default class KVKSFileWriter {
|
|||
|
||||
public kvkShiftToKvksShift(shift: VisualKeyboardShiftState): string {
|
||||
// TODO-LDML(lowpri): make a map of this?
|
||||
for(let state of VisualKeyboardLegalShiftStates) {
|
||||
for(const state of VisualKeyboardLegalShiftStates) {
|
||||
if(state.shift == shift) {
|
||||
return state.name;
|
||||
}
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
import * as xml2js from '../deps/xml2js/xml2js.js';
|
||||
import { SchemaValidators, util } from '@keymanapp/common-types';
|
||||
import { xml2js } from '../../index.js';
|
||||
import { CommonTypesMessages } from '../../common-events.js';
|
||||
import { CompilerCallbacks } from '../../compiler-interfaces.js';
|
||||
import { LDMLKeyboardXMLSourceFile, LKImport, ImportStatus } from './ldml-keyboard-xml.js';
|
||||
import { boxXmlArray } from '../util/util.js';
|
||||
import { CompilerCallbacks } from '../util/compiler-interfaces.js';
|
||||
import { constants } from '@keymanapp/ldml-keyboard-constants';
|
||||
import { CommonTypesMessages } from '../util/common-events.js';
|
||||
import { LDMLKeyboardTestDataXMLSourceFile, LKTTest, LKTTests } from './ldml-keyboard-testdata-xml.js';
|
||||
import SchemaValidators from '../schema-validators.js';
|
||||
|
||||
import boxXmlArray = util.boxXmlArray;
|
||||
|
||||
interface NameAndProps {
|
||||
'$'?: any; // content
|
||||
|
|
@ -22,7 +23,7 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
}
|
||||
|
||||
static get defaultImportsURL(): [string,string] {
|
||||
return ['../import/', import.meta.url];
|
||||
return ['../../import/', import.meta.url];
|
||||
}
|
||||
|
||||
readImportFile(version: string, subpath: string): Uint8Array {
|
||||
|
|
@ -63,10 +64,10 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
boxXmlArray(source?.keyboard3?.locales, 'locale');
|
||||
boxXmlArray(source?.keyboard3, 'transforms');
|
||||
if(source?.keyboard3?.layers) {
|
||||
for(let layers of source?.keyboard3?.layers) {
|
||||
for(const layers of source?.keyboard3?.layers) {
|
||||
boxXmlArray(layers, 'layer');
|
||||
if(layers?.layer) {
|
||||
for(let layer of layers?.layer) {
|
||||
for(const layer of layers?.layer) {
|
||||
boxXmlArray(layer, 'row');
|
||||
}
|
||||
}
|
||||
|
|
@ -74,13 +75,13 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
}
|
||||
if(source?.keyboard3?.forms?.form) {
|
||||
boxXmlArray(source?.keyboard3?.forms, 'form');
|
||||
for(let form of source?.keyboard3?.forms?.form) {
|
||||
for(const form of source?.keyboard3?.forms?.form) {
|
||||
boxXmlArray(form, 'scanCodes');
|
||||
}
|
||||
}
|
||||
if(source?.keyboard3?.flicks) {
|
||||
boxXmlArray(source?.keyboard3?.flicks, 'flick');
|
||||
for(let flick of source?.keyboard3?.flicks?.flick) {
|
||||
for(const flick of source?.keyboard3?.flicks?.flick) {
|
||||
boxXmlArray(flick, 'flickSegment');
|
||||
}
|
||||
}
|
||||
|
|
@ -90,9 +91,9 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
boxXmlArray(source?.keyboard3?.variables, 'uset');
|
||||
}
|
||||
if(source?.keyboard3?.transforms) {
|
||||
for(let transforms of source.keyboard3.transforms) {
|
||||
for(const transforms of source.keyboard3.transforms) {
|
||||
boxXmlArray(transforms, 'transformGroup');
|
||||
for (let transformGroup of transforms.transformGroup) {
|
||||
for (const transformGroup of transforms.transformGroup) {
|
||||
boxXmlArray(transformGroup, 'transform');
|
||||
boxXmlArray(transformGroup, 'reorder');
|
||||
}
|
||||
|
|
@ -235,8 +236,8 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
* @returns true if valid, false if invalid
|
||||
*/
|
||||
public validate(source: LDMLKeyboardXMLSourceFile | LDMLKeyboardTestDataXMLSourceFile): boolean {
|
||||
if(!SchemaValidators.ldmlKeyboard3(source)) {
|
||||
for (let err of (<any>SchemaValidators.ldmlKeyboard3).errors) {
|
||||
if(!SchemaValidators.default.ldmlKeyboard3(source)) {
|
||||
for (const err of (<any>SchemaValidators.default.ldmlKeyboard3).errors) {
|
||||
this.callbacks.reportMessage(CommonTypesMessages.Error_SchemaValidationError({
|
||||
instancePath: err.instancePath,
|
||||
keyword: err.keyword,
|
||||
|
|
@ -250,9 +251,9 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
}
|
||||
|
||||
loadUnboxed(file: Uint8Array): LDMLKeyboardXMLSourceFile {
|
||||
let source = (() => {
|
||||
const source = (() => {
|
||||
let a: LDMLKeyboardXMLSourceFile;
|
||||
let parser = new xml2js.Parser({
|
||||
const parser = new xml2js.Parser({
|
||||
explicitArray: false,
|
||||
mergeAttrs: true,
|
||||
includeWhiteChars: false,
|
||||
|
|
@ -289,9 +290,9 @@ export class LDMLKeyboardXMLSourceFileReader {
|
|||
}
|
||||
|
||||
loadTestDataUnboxed(file: Uint8Array): any {
|
||||
let source = (() => {
|
||||
const source = (() => {
|
||||
let a: any;
|
||||
let parser = new xml2js.Parser({
|
||||
const parser = new xml2js.Parser({
|
||||
// explicitArray: false,
|
||||
preserveChildrenOrder:true, // needed for test data
|
||||
explicitChildren: true, // needed for test data
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { loadFile, resolveFilename } from '../helpers/index.js';
|
||||
import { CompilerCallbacks, CompilerError, CompilerEvent, CompilerFileSystemCallbacks, CompilerPathCallbacks } from '../../src/util/compiler-interfaces.js';
|
||||
import { loadFile, resolveFilename } from './helpers/index.js';
|
||||
import { CompilerCallbacks, CompilerError, CompilerEvent, CompilerFileSystemCallbacks, CompilerPathCallbacks } from '../src/compiler-interfaces.js';
|
||||
|
||||
// This is related to developer/src/common/web/test-helpers/index.ts but has a slightly different API surface
|
||||
// as this runs at a lower level than the compiler.
|
||||
|
|
@ -40,7 +40,7 @@ export class TestCompilerCallbacks implements CompilerCallbacks {
|
|||
return loadFile(filename);
|
||||
} catch (e) {
|
||||
if (e.code === 'ENOENT') {
|
||||
return null;
|
||||
return <Uint8Array><unknown>null;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||