Perl - copy to clipboard in cp1251

416 Views Asked by At

Trying to copy to clipboard text in cp1251.

#!/usr/bin/perl -w

use Clipboard;
use Encode;

    my $ClipboardOut = "A bunch of cyrillic characters - а-б-в-г \n";
    Encode::from_to($ClipboardOut, 'utf-8', 'cp1251');

    Clipboard->copy($ClipboardOut);

Instead of Cyrillic letters "?" are pasted in any Windows apps. If I remove line with Encode - Cyrillic letters produce "a'-s with different modifiers:

A bunch of cyrillic characters   à-á-â-ã 

I guess I miss something extra-simple but I'm stuck on it. Can somebody help me, please?

2

There are 2 best solutions below

10
ikegami On

In Windows, Clipboard expects text encoded using the system's Active Code Page. That's because Clipboard is just a wrapper for Win32::Clipboard. And while Win32::Clipboard allows you to receive arbitrary Unicode text from the clipboard, it doesn't allow you to place arbitrary Unicode text on the clipboard. So using that module directly doesn't help.

This is limiting. For example, my machine's ACP is cp1252, so I wouldn't be able to place Cyrillic characters on the clipboard using this module.

Assuming your system's ACP supports the Cyrillic characters in question, here are two solutions: (I used Win32::Clipboard directly, but you could use Clipboard the same way.)


Source code encoded using UTF-8 (This is normally ideal)

use utf8;

use Encode           qw( encode );
use Win32            qw( );
use Win32::Clipboard qw( );

# String of decoded text aka Unicode Code Points because of `use utf8;`
my $text_ucp = "а-б-в-г\n";

my $acp = "cp" . Win32::GetACP();
my $clip = Win32::Clipboard();
$clip->Set(encode($acp, $text_ucp));

Source code encoded as per Active Code Page

Perl expects source code to be encoded using ASCII (no utf8;, the default) or UTF-8 (with use utf8;). However, string and regex literals are "8-bit clean" when no utf8; is in effect (the default), meaning that any byte that doesn't correspond to an ASCII character will result in a character with the same value as the byte.

use Win32::Clipboard qw( );

# Text encoded using source's encoding (because of lack of `use utf8`),
# which is expected to be the Active Code Page.
my $text_acp = "а-б-в-г\n";

my $clip = Win32::Clipboard();
$clip->Set($text_acp);
3
Disco On

Found temporary solution: script generates .bat file with echo blah-blah-blah | clip, run it and then delete.