Thursday, July 15, 2010

Emeditor with ActivePerl

다음은 EmEditor의 PerlScript를 이용해서 hiveminder에 글을 올리는 post입니다.

  1. #language = "PerlScript"  
  2. use utf8;  
  3. use Net::Hiveminder;  
  4.   
  5. my $hm = Net::Hiveminder->new(email => 'your@email.com', password => 'yourpassword');  
  6. my $text = $Window->prompt('Add Hive Minder Summary''');  
  7. $hm->create_task(Encode::encode("euckr", $text));  
  8.   
  9. $Window->Alert('done');  


저는 단축키 alt-v로 이 매크로가 실행되도록 해두었습니다.





이렇게 올린 todo는 바로바로 iphone의 iMinder(무료)로 확인할 수 있고 편집할 수 있습니다.



그런데 hiveminder에 올리는 summary에 한글과 영어이외에 일본어나 중국어등의 utf-8코드를 사용하고 싶다면 이하의 방법을 사용해야 합니다.

  1. #language = "PerlScript"  
  2. use encoding "utf8";  
  3. use utf8;  
  4. use Win32::OLE;  
  5. use Net::Hiveminder;  
  6.   
  7. my $vbscript = Win32::OLE->new('ScriptControl');  
  8.   
  9. $vbscript->{Language} = 'JScript';  
  10. $vbscript->AddObject("window", $Window);        # Emeditor의 DOM의 하나인 윈도우 객체를 넘긴다.  
  11. $vbscript->AddCode(<<JScript);  
  12. function writeFileAsUTF8WithoutBOM(filepath, content) {  
  13. /* ADODB.Stream - SaveOptionsEnum */  
  14. var adSaveCreateOverWrite = 2;  
  15.   
  16. /* ADODB.Stream - StreamTypeEnum */  
  17. var adTypeBinary = 1, adTypeText = 2;  
  18.   
  19. /* ADODB.Stream - StreamWriteEnum */  
  20. var adWriteChar = 0, adWriteLine = 1;  
  21.   
  22. var st = new ActiveXObject("ADODB.Stream");  
  23. st.type = adTypeText;  
  24. st.charset = "utf-8";  
  25. st.open();  
  26.   
  27. st.WriteText( content, adWriteLine );  
  28.   
  29. st.Position = 0;  
  30. st.Type = adTypeBinary;  
  31. st.Position = 3; // to skip BOM  
  32. var bin = st.Read();  
  33. st.Close();  
  34.   
  35. var stw = new ActiveXObject("ADODB.Stream");  
  36. stw.Type = adTypeBinary;  
  37. stw.Open();  
  38. stw.Write( bin );  
  39. if (filepath == '') {  
  40.     alert('filepath is empty!');  
  41. }  
  42. stw.SaveToFile(filepath , adSaveCreateOverWrite );  
  43. stw.Close();  
  44. }  
  45. function saveprompt() {  
  46. var str = window.prompt('Add Hive Minder Summary'new Date);  
  47. writeFileAsUTF8WithoutBOM('c:\\\\_hiveminder.txt', str);  
  48. }  
  49. JScript  
  50.   
  51. #$vbscript->Run('saveprompt', null);  
  52. $vbscript->Eval('saveprompt()');  
  53.   
  54. my $hm = Net::Hiveminder->new(email => 'your@email.com', password => 'yourpassword', );  
  55. open (my $fh, "<:utf8""c:\\_hiveminder.txt") or $window->alert("Cannot open $file: $!");  
  56. my $text = <$fh>;  
  57. $hm->create_task($text);  
  58.   
  59. #$window->Alert(Encode::encode("UCS-2LE", $text));  <--- doesn't work  
  60. #$window->Alert(Encode::encode("UCS-2BE", $text));  <--- doesn't work  
  61. #$window->Alert(Encode::encode("utf8", $text));  <--- doesn't work  
  62. #$window->Alert(Encode::encode("utf16", $text));  <--- doesn't work  
  63.   
  64. $Window->Alert('done');  







이렇게 해야하는 이유는 Emeditor는 ScriptingControl 이라는 ActiveX를 통해서 ActivePerl의 인스턴스를 만들어 내고
소스 문자열을 그대로 이 ScriptingControl에 건내, Eval이나 Run 인터페이스를 통해 실행하는 방식을 취하고 있는데
ActivePerl에서는 유니코드가 내부적으로 utf16이 아닌 utf-8을 사용하고 있고, 윈도우즈는 유니코드를 내부적으로 utf-16(정확히는 UCS-2)을 사용하고 있는데
이 부분에서 WideChar의 전달이 망가지기 때문입니다.

# 전달받지 않고 Perl안에서 할당하고 처리하는 코드는 잘 문제없습니다.

결국 이런 회피법으로 피해가고 있습니다만, 좀 더 똑똑한 방법이 있는 지는 모르겠습니다.
Python도 내부적으로 UCS-2입니다만, Hiveminder의 Python라이브러리가 없습니다.
# 만들면 되는데, Hiveminder의 Api의 설명문서가 제대로 갱신되어 있지 않습니다. 많은 시간 들여 해봤는데 403 forbidden이 나옵니다.
# 전달해야하는 파라메터는 훨씬 더 많은 것 같습니다.

그런데 위쪽의 방법으로 하면 되는 이유는 OS에서는 어째서인지 명확히 설명할 수는 없지만, 시스템 디폴트코드페이지는 먹히기 때문입니다.
# 실제로는 저는 일본 OS이기 때문에 sjis로 decode하고, 일본어만 사용할 수 있습니다.

좀 더 현명한 방법이 있으면 공유 부탁드립니다. m(_ _)m

No comments: