How to type text in Russian from clipboard using applescript without changing the system language on the Mac?

Viewed 228

I automate the filling of forms in Latin alphabet, but in one place there is a field where i need to type the text in Russian.

Before filling in, I copy the desired word in Russian and I want to type it from the clipboard without changing system language / encoding / charset.

In other words. Just type a word from the clipboard in Russian letters and continue working with the Latin alphabet.

How can this be done using applescript?

set r to the clipboard
write_string(r as text)

on write_string(the_string)
    tell application "System Events"
        
        repeat with the_character in the_string
            keystroke the_character
            delay (random number from 0.05 to 0.25)
        end repeat
        
    end tell
end write_string

Shell i use this part like that or something?

write_string(r as text) encode('utf8')?

The solution to just copy and paste the word in Russian does not work. It needs to be written.

Please, direct which way to dig. Any ideas?

3 Answers

user3439894, hello! For a temporary language change, your code for Big Sur works. Thank you. I only made small changes (delay + command).

set the clipboard to " Как это можно сделать с помощью?"
set r to the clipboard
write_string(r as text)

on write_string(the_string)
    
    tell application "System Events"
        key code 49 using command down --   ⌃Space
        delay 0.5
        repeat with the_character in the_string
            keystroke the_character
            delay (random number from 0.05 to 0.25)
        end repeat
        delay 0.5
        key code 49 using command down --   ⌃Space
    end tell
    
end write_string

But I would like to find a solution when the algorithm itself understands in what encoding to write the copied text. Do you think this is possible if, for example, instead of the Russian language (which I have installed in the system), I copy Japanese characters and the algorithm will enter exactly the Japanese characters into the field? Maybe with javascript?

This solution uses code written by jackjr300 in his answer: Is it possible to keystroke special characters in AppleScript?

Using Xcode, I created the command line tool TypeCharacters and copied it to /usr/local/bin/

I then incorporated it into the following example AppleScript code:

set the clipboard to "Русские персонажи & 日本語の文字"

set thisText to the clipboard

tell application "Safari" to activate
delay 0.5

my typeCharactersOf(thisText)

to typeCharactersOf(thisString)
    set theStringList to characters of thisString
    repeat with thisCharacter in theStringList
        do shell script ¬
            "/usr/local/bin/TypeCharacters " & ¬
            quoted form of thisCharacter
        delay (random number from 0.05 to 0.25)
    end repeat
end typeCharactersOf

The output of which was:

enter image description here


Notes:

I used Google Translate to translate "Russian characters" to Russian, Русские персонажи, and "Japanese characters" to Japanese, 日本語の文字.

Testing by writing to Safari at this website into an answer text box the results were the same regardless of what the input source was set to.

The example AppleScript code, shown above, was tested in Script Editor under macOS Catalina with Language & Region settings in System Preferences set to English (US) — Primary and two input sources in System Preferences > Keyboard > Input Sources, U.S. and Russian, and worked for me without issue1.

  • 1 Assumes necessary and appropriate settings in System Preferences > Security & Privacy > Privacy have been set/addressed as needed.

Code used from the linked answer to create the command line tool TypeCharacters in Xcode:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        if (argc > 1) {
            NSString *theString = [NSString stringWithUTF8String:argv[1]];
            UniChar uChar;
            CGEventRef keyEvent = CGEventCreateKeyboardEvent(nil, 0, true);
            for (int i = 0; i < [theString length]; i++)
            {
                uChar = [theString characterAtIndex:i];
                CGEventKeyboardSetUnicodeString(keyEvent, 1, &uChar);
                CGEventPost(kCGHIDEventTap, keyEvent); // key down
                CGEventSetType(keyEvent, kCGEventKeyUp);
                CGEventPost(kCGHIDEventTap, keyEvent); // key up (type the character)
                CGEventSetType(keyEvent, kCGEventKeyDown);
                [NSThread sleepForTimeInterval:0.001]; // wait 1/1000 of second, no need of this line on my computer, I use 0.001 to be safe, increase it If you still have issues
            }
            CFRelease(keyEvent);
        }
    }
    return 0;
}


Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.

When System Events uses keystroke or key code it does so in the context of the selected input source as listed in: System Preferences > Keyboard > Input Sources

In other words, using the Google Translate of "How can this be done?" in Russian, "Как это можно сделать с помощью?", copied to the clipboard and my current input source is U.S., then System Events outputs: aaa aaa aaaaa aaaaaaa a aaaaaaa?

To get "Как это можно сделать с помощью?" one needs to manually switch or programmatically switch the input source to e.g. Russian while System Events uses keystroke to produce the desired results.

The example AppleScript code, shown below, was tested in Script Editor under macOS Catalina with Language & Region settings in System Preferences set to English (US) — Primary and two input sources in System Preferences > Keyboard > Input Sources, U.S. and Russian, and worked for me without issue1.

  • 1 Assumes necessary and appropriate settings in System Preferences > Security & Privacy > Privacy have been set/addressed as needed.

Example AppleScript code:

set the clipboard to "Как это можно сделать с помощью?"

set theRussianText to the clipboard

my writeString(theRussianText)

to writeString(theString)
    set theStringList to characters of theString
    tell application "System Events"
        key code 49 using control down --   ⌃Space
        delay 0.25
        repeat with thisCharacter in theStringList
            keystroke thisCharacter
            delay (random number from 0.05 to 0.25)
        end repeat
        key code 49 using control down --   ⌃Space
    end tell
end writeString

Notes:

This uses the default keyboard shortcut, in System Preferences > Keyboard > Shortcuts > Input Sources, to select the previous input source and since I only have two listed and was already set to U.S., ⌃Space switched to Russian and then back to U.S. when executed a second time.

If you have more than two input sources in System Preferences > Keyboard > Input Sources, then you will need to go about it differently.

As an example, I used the third-party utility InputSourceSelector, as in the following example AppleScript code:

set the clipboard to "Как это можно сделать с помощью?"

set theRussianText to the clipboard

my writeString(theRussianText)

to writeString(theString)
    set theStringList to characters of theString
    my switchInputSourceTo("com.apple.keylayout.Russian")
    delay 0.25
    tell application "System Events"
        repeat with thisCharacter in theStringList
            keystroke thisCharacter
            delay (random number from 0.05 to 0.25)
        end repeat
    end tell
    my switchInputSourceTo("com.apple.keylayout.US")
end writeString

to switchInputSourceTo(thisInputSource)
    do shell script ¬
        "/usr/local/bin/InputSourceSelector" & ¬
        space & "select" & space & thisInputSource
end switchInputSourceTo


As you can see at the bottom of this clipped screenshot, from Script Editor, shown in purple text, "Как это можно сделать с помощью?" was typed.

enter image description here



Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.

Related