- Home
-
Training Materials
- Keyboards and Fonts
- Linguistics
- Literacy
- Oral Translation
- Others
- Scripture Use
-
Translation
- Scripture Forge
- Adapt-It
- OmegaT Translation Memory Tool
-
Paratext
- Paratext 9 Materials
- Paratext 8 Course Manuals
- Paratext 7.5 Course and Handbook
- Paratext 7.1 Basic Training
-
Paratext Tutorials
- Basic Editing
- Language Source Tools in Paratext 7.6
- View menu tutorial
- Basic introduction to USFMs
- Tips and Tricks
- Introduction to Using Notes
- Cookbook for Consultants
- Menus vary by active project
- Vérifications
- Help! Paratext has stopped working
- Help, send and receive is not working!
- Bible Modules
- Which Paratext Tool When
- Paratext-FLEx Integration Tutorial
- Back Translations and Interlinearizer
- Send-receive and backing up your data
- ParaTExt 8 Test Projects
- New features in Paratext 8
- Voice Marking Tools
- Animated introduction to Paratext and the stages of a translation project
- Setting up a Paratext Project for Success
- Import TXT or Word DOC Files into Paratext Using SILAS
- Illustrations and Maps
- Advanced Unicode handling
- Create a Custom Python Script in the Paratext Menu
- Create a Custom Scripture Check in the Paratext Menu
-
Translator's Workplace
- Adding BdT Menu to Logos 10
- Adding TW Menu to Logos 10
- Logos Bible Software
-
Translator's Workplace Logos Edition
- Logos 8 Get Started Manual
- Opening Logos
- Opening a Resource
- Navigating a Resource
- Reading Multiple Versions
- Basic Search
- Bible Search
- Looking for Bible Facts
- Using the Home Page
- Using the Passage Guide
- Using the Exegetical Guide
- Using the Bible Word Study Guide
- Using the Sermon Starter Guide
- Using the Topic Guide
- Studying English Words Using the Bible Word Study Guide
- Studying Hebrew and Greek Words Using the Bible Word Study Guide
- Prepare a Bible Lesson Using the Sermon Starter Guide
- Look for Information on a Topic Using the Topic Guide
- Saving Your Workspace or Layout
- Arranging the Windows
- Study a Word Using a Reverse Interlinear
- Study a Word Using a Morphology Search
-
Logos edition
- Logos 8 Get Started Manual
- Set up TW Logos for Success
- Quickstart Guide
- Advanced Tips
- Scrolling with other Translation Programs
- Transition from TWFolio
- Troubleshooting
- External Resources
- Low Bandwidth Installation and Updates
- Turn off Logos internet use when visiting a low bandwidth area
- Logos for Beginners Video-based Training
- Translation Workplace - Folio edition
-
Consultant Training
-
Regional Workshops
- Africa Kenya Workshops(LTCT)
- 2021 Africa Virtual Workshop
- 2020 Africa Nairobi
- 2019 Africa Nairobi
- 2018 Africa Nairobi
- 2017 Africa Nairobi
-
2016 Africa Nairobi
- Course Objectives 2016
- Course Schedule 2016
-
Course Program 2016
- HearThis Session 4
- FLEx 8 Lexicon Edit
- FLEX 8 Using text to build lexicon
- LTCT2016 FLEx - Export
- Scripture App Builder Day 1
- LTCT2016 WeSay New Projct
- Create a new project from a FLEX Lift File
- LTCT2016 Wesay Wordlist
- LTCT2016 WeSay Collaboration
- Scripture App Builder Day 1B
- Scripture App Builder Day 1C
- Scripture App Builder Day1D
- Scripture App Builder Day 2A
- Scripture App Builder Day 2A
- Scripture App Builder Day 2B
- Scripture App Builder Day 2C
- Scripture App Builder Day 2D
- Scripture App Builder Day 3A
- Scripture App Builder Day 3B
- Scripture App Builder Day 3C
- Scripture App Builder Day 3D
- LTCT2016 RegExp
- LTCT2016 Paratext1
- Evening Sessions 2016
- Morning Sharing Time 2016
- Responsibilities 2016
- LTCT 2016 Evaluation
- 2015 Africa Nairobi
- 2014 Africa Nairobi
- 2014 Africa Kara, Togo
- 2013 Africa Nairobi
-
2012 Africa Nairobi
- Course Objectives 2012
- Course Program 2012
- LTCT2012 Friday Jan 20
- LTCT2012 Thursday Jan 19
- LTCT2012 Wednesday Jan 18
- LTCT2012 Tuesday Jan 17
- LTCT2012 Monday jan 16
- LTCT2012 Saturday Jan 14
- LTCT2012 Friday Jan 13
- LTCT2012 Thursday Jan 12
- LTCT2012 Wednesday Jan11
- LTCT2012 Tuesday Jan 10
- LTCT 2012 Monday Jan9
- LTCT2012 Evaluation
- Proactive Software Training
- Teaching a Workshop
-
Paratext for Consultants
- 1 Arranging your workspace
- 2 Consultant notes
- 3 Searching and Dictionaries
- 4 Send and receive
- 5 Taking notes during checking
- 6 Keeping track of Biblical term renderings
- 7 Using the Biblical terms tool
- 8 Seeing history and comparing versions
- 9 Understanding the vernacular text
- 10 Spell checking
- Video lessons
- Paratext Supporters
- Digital Publishing
-
Regional Workshops
- Webinars
- Resources
-
»
- How to Modify a Keyman Keyboard
This lesson is for dealing with existing keyboards that have not yet been uploaded to keyman.com. If the project already exists on keyman.com, to edit it, you will have to pull it down from GitHub to your local computer before making modifications.
Create a folder for Keyman projects on your hard drive
In the past, Keyman files were stored in \Documents\Keyman\. Check to see if you have that directory and look at what is in there. If you have existing projects, you have two choices:
- Move them elsewhere and use the empty Keyman folder for Keyman 11+ projects
- Create a different data directory for Keyman that will only contain data managed by Keyman 11+
Starting with Keyman Developer 11, the project directory structure is in the format needed for uploading keyboards to the Keyman.com repository. It also includes the source files inside the folder so that they can be modified and updated.
Creating a project to contain it
When opening Keyman Developer, it will open the last project you were working on
- Select Create a New Project from the Project menu
- Choose Basic.
(The option to import a Windows keyboard is about importing a Windows system keyboard to use as a starting point, not a Keyman keyboard) - Name the keyboard, assign copyright, version, author
- Targets
The default is "any". Since this includes all the others, we can leave this. Since Keyman 10, a single keyboard package can contain keyboards that will work on all major platforms. - Set the Path
At the time of this tutorial, the default path was set to "Documents", which would make every keyboard a subdirectory of Documents. Not a good option! Make sure to select the directory you designated at the beginning of this document. - Keyboard ID
The proposed name must be all lowercase. This is important for the Keyman.com directory structure. - Languages
- Choose Add language...
- Select the appropriate BCP47 (or ISO 639-3) code for each language the keyboard will support. You can usually find these codes on ethnologue.com. For Windows keyboards, the language code should also include the script. Keyman already inserts what it thinks the script is for the language you choose, but you can correct this if needed.
- Select OK
Keyboard tab
- Click on the Keyboards tab on the bottom of the project window
- Open the keyboard by clicking on the blue link with the keyboard name.
- Click on the Layout tab on the left.
You are looking at the visual keyboard. Normally we would start here and then switch to the code view, but since we are importing an existing keyboard, we will start with the code view. - Open your existing keyboard file in a text editor, copy the contents and paste them at the bottom of this window.
- Fix the header by manually merging the header information between the two files.
You can move the old comment fields if any to the top, and remove these lines (near the top) if your original file already has them:
begin Unicode > use(main) group(main) using keys
Save and compile
Jump ahead to the build tab on the bottom left and try to compile the keyboard. If it compiles, great! You are ready to start doing modifications. If it doesn't compile, check the warnings and fix the problems. You may get warnings about header statements being deprecated, or old code in the kmn file that is deprecated:
ibani.kmn: Compiling 'C:\Users\higby\Documents\Keyman\ibani\source\ibani.kmn' for Windows, macOS, Linux, Desktop devices... ibani.kmn: Warning: line 22 warning 209D: Header statements are deprecated; use instead the equivalent system store ibani.kmn: Error: 'C:\Users\higby\Documents\Keyman\ibani\source\ibani.kmn' was not compiled successfully for Windows, macOS, Linux, Desktop devices.
Old style headers in Keyman were written as
HOTKEY "%+I"
and the new style of headers is
store(&hotkey) "[ALT K_I]"
Understanding the Keyman Code
Now we are at the point where you will have to study and know something about the Keyman code.
Simple key swapping statements
It could be that your keyboard uses simple swap statements like this:
';\' + 'i' > 'i' U+0300 c i grave
This statement says:
If an i is typed following ;\ replace everything to the left of the > with the characters on the right. This works, but results in long and inefficient code because the comand needs to be repeated over and over for every character that you want to modify.
Using Variables and indexes
In keyboards that take advantage of the strength of the Keyman language, you will find store, any and index statements. The store statement creates a named variable. With variables, you can issue a single swap command that works on every character stored inside it. Here is a simple example of how these three statements are used:
store(vowelKey) 'aeiou' store(vowelAcute) 'áéíóú' any(vowelKey) + "/" > index(vowelAcute, 1)
In the above example, store(vowelKey) assigns the set of characters "aeiou" to the named variable "vowelKey". Now, you can reference the characters stored in it at any time with the any(vowelKey) statement.
The first two lines above assign sets of characters to two variables. The order of the characters in the set is very important! When Keyman is called to replace a character in the first variable with a character in the second variable, it counts the position of the character in the store found with the any() statement and outputs the character in the same position in the index() statement.
Index position
The number in the index statement is important because it tells it which character in the context (part that preceeds the > to get the index value from. This doesn't seem necessary in the statement above, but in the example below, the index is based on the second character in the context, so it must be set to 2:
deadkey(Acute) + any(vowelKey) > index(vowelAcute, 2)
For further reference
Stores are best explained on the Keyman website here:
The Keyman website has a complete code reference that you will have to get familiar with. Read up on how the code works.
Keyman Developer Keyboard Tutorial
Adding a character to an existing keyboard
The most common reason we get asked to edit an existing keyboard is to add a character that is missing. We will include an example here of the Ibani keyboard which wants the addition of a dot below the letter d. In Unicode, the desired character is U+0323 Combining dot below.
This is quite an easy assignment because the keyboard already contains a keystroke sequence to produce the dot below on b and s.
Ibani keyboard coding exercise
We won't show the whole original keyboard -- as it is not the most efficient coding. Here is enough for you to observe and discover where and how to insert the additional code to make the dot appear under both upper and lowercase d.
begin Unicode > use(Main) store(Let2BMod) "cdghkmnyzCDGKLMNXY$?*" store(ModLet) "çɗɡɦƙɲŋƴʒÇƊɣƘ£ƝŊƎƳ₦ʔ°" store(Let2BDot) "bBsS" store(vowel) "aeiouAEIOU" store(vAcute) "áéíóúÁÉÍÓÚ" store(vMid) "āēīōūĀĒĪŌŪ" store(vGrave) "àèìòùÀÈÌÒÙ" store(vCircum) "âêîôûÂÊÎÔÛ" store(vCaron) "ǎěǐǒǔǍĚǏǑǓ" store(vDot) "ạẹịọụẠẸỊỌỤ" store(nasal) "mnMN" store(nAcute) "ḿńḾŃ" store(LetN) "nN" store(nGrave) "ǹǸ" store(nCaron) "ňŇ" group(main) using keys c deadkeys are identified c single deadkeys + ";" > deadkey(modlet) c applies to dotted vowels and Letters to be modified + "'" > deadkey(acute) + "-" > deadkey(mid) + "`" > deadkey(grave) + "^" > deadkey(circum) + "&" > deadkey(caron) + "!" > deadkey(downstep) c single deadkeys are cleared when typed twice (dk acute has a second use here) dk(modlet) + ";" > ";" dk(acute) + "'" > U+02C8 c modifier letter vertical line (ˈ) U+02C8 + "'" > "'" c just an acute accent dk(mid) + "-" > "-" dk(grave) + "`" > "`" dk(circum) + "^" > "^" dk(caron) + "&" > "&" dk(downstep) + "!" > "!" c 1st set (;) combo deadkeys for tones on dotted vowels (order does not matter) dk(modlet) + "'" > deadkey(dotAcute) dk(acute) + ";" > deadkey(dotAcute) dk(modlet) + "-" > deadkey(dotMid) dk(mid) + ";" > deadkey(dotMid) dk(modlet) + "`" > deadkey(dotGrave) dk(grave) + ";" > deadkey(dotGrave) dk(modlet) + "^" > deadkey(dotCircum) dk(circum) + ";" > deadkey(dotCircum) dk(modlet) + "&" > deadkey(dotCaron) dk(caron) + ";" > deadkey(dotCaron) dk(modlet) + "!" > deadkey(dotDownstep) dk(downstep) + ";" > deadkey(dotDownstep) c assignments c plain letters are modified, vowels are dotted dk(modlet) + any(Let2BMod) > index(ModLet,2) dk(modlet) + any(vowel) > index(vDot,2) dk(modlet) + any(Let2BDot) > index(Let2BDot,2) U+0323 c plain vowels & nasals are tone marked dk(acute) + any(vowel) > index(vAcute,2) dk(acute) + any(nasal) > index(nAcute,2) dk(mid) + any(vowel) > index(vMid,2) dk(mid) + any(nasal) > index(nasal,2) U+0304 dk(grave) + any(vowel) > index(vGrave,2) dk(grave) + any(LetN) > index(nGrave,2) dk(circum) + any(vowel) > index(vCircum,2) dk(circum) + any(nasal) > index(nasal,2) U+0302 dk(caron) + any(vowel) > index(vCaron,2) dk(caron) + any(LetN) > index(nCaron,2) dk(downstep) + any(vowel) > index(vowel,2) U+030B dk(downstep) + any(nasal) > index(nasal,2) U+030B
Observations about the above code
The key sequence ; + s produces ṣ -- so it would be easy to add d to the same store.
However, ; + d is already used to produce this character: ɗ
What can we do? Fortunately the hooked d is not needed in the Ibani orthography and may be removed from the code.
The semicolon is pressed and becomes deadkey(modlet) in line 22.
deadkey(modlet) is used to produce the dot below the s and b in line 58.
deadkey(modlet) is also used on store(ModLet) to swap with store(Let2BMod) in line 56
You can try to solve this by pasting the above code into Keyman Developer (or if following in class, use the file provided).
When you think you have found the solution, click below to compare your results
d, D and their swap characters ɗ, Ɗ must be removed from the Let2BMod and ModLet stores as follows: store(Let2BMod) "cghkmnyzCGKLMNXY$?*" store(ModLet) "çɡɦƙɲŋƴʒÇɣƘ£ƝŊƎƳ₦ʔ°"
Then d and D must be added to the Let2BDot store: store(Let2BDot) "bBsSdD"
Once you figure out what the code is doing, it is easy!
Your job is finished in so far as your client will be happy! However, we have only done the minimum that was required. Do you want one happy client or do you want a thousand happy clients? For that to happen, we'll have to prepare this file and its documentation for uploading to Keyman.com