Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Google translate in tooltip [Still Works]


  • Please log in to reply
64 replies to this topic
micdelt
  • Members
  • 7 posts
  • Last active: Jul 01 2013 08:52 PM
  • Joined: 11 Dec 2009
Some replacement for Abbyy Lingvo / Stardict. Activated by double press Ctrl+C. First press copies text to clipboard, next translate it. Translated text appears in tooltip.

Old code no longer works. This is a new one.
Requeres Unicode version of AutoHotkey.
;--------------------------------------------------
; Translate text using translate.google.com 
; after Google Translate API deprecation
;
; Ctrl+C, Ctrl+C
; Author: Mikhail Kuropyatnikov (micdelt@mail.ru), 
;       Volgograd, Russia
;--------------------------------------------------
#NoEnv

~^C:: DoublePress()

DoublePress()
{
   static pressed1 = 0
   if pressed1 and A_TimeSincePriorHotkey <= 200
   {
      pressed1 = 0
	  ; Translate from any language to Russian and from Russian to English if source was in Russian
      Translate("ru","en") 
   }
   else
      pressed1 = 1
   
}

; translate to "to" language,
; if source language is "to" 
; translate to "anti" language

Translate(To,Anti)
{
   UseAnti = 0
   TranslateTo := To
   if Clipboard = 
       return

   UriCli := UriEncode(Clipboard)

anti_translate:
   Url := "http://translate.google.com/translate_a/t?client=x&text="
            . UriCli . "&tl=" . TranslateTo

   ; Simulate Google Chrome
   JsonTrans := UrlDownloadToVar(Url,"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/18.6.872.0 Safari/535.2")

   ; thanks to Grey (http://forum.script-coding.com/profile.php?id=25792)
   StringReplace, JsonTrans, JsonTrans, \r\n,`r`n, All
   StringReplace, JsonTrans, JsonTrans, \", ", All
   FromLang:=JSON(JsonTrans, "src")
   ElapsedTime:=JSON(JsonTrans, "server_time")

   if (FromLang == To and TranslateTo <> Anti)
   {
      TranslateTo := Anti
      ;MsgBox % FromLang . " " . To . " " TranslateTo . " " . Anti
      goto anti_translate
   }

   Loop
   {
     Sentence:=JSON(JsonTrans, "sentences["(A_Index-1)"].trans")
     If Sentence
       TransText.=Sentence
     Else
       Break
   }
   
   ; Convert To UTF-8
   BaseFileEnc := A_FileEncoding
   FileEncoding
   FileDelete, %A_ScriptDir%\Convert.html 
   FileAppend, %TransText%, %A_ScriptDir%\Convert.html 
   FileEncoding, UTF-8
   FileRead TransText, %A_ScriptDir%\Convert.html 
   FileEncoding, %BaseFileEnc%
   
   ; split long line to smaller lines about 40-50 symbols length
   t := RegExReplace(transText,".{40,50}(\s)","$0`n")
   
   ToolTip %FromLang%: %t%
   ; copy result to clipboard
   clipboard := t
   
}



~LButton::
ToolTip
return



UrlDownloadToVar(URL, UserAgent = "", Proxy = "", ProxyBypass = "") {
    ; Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation 4.0,
    ; Windows Me, Windows 98, or Windows 95.
    ; Requires Internet Explorer 3.0 or later.
    pFix:=a_isunicode ? "W" : "A"
    hModule := DllCall("LoadLibrary", "Str", "wininet.dll")

    AccessType := Proxy != "" ? 3 : 1
    ;INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration
    ;INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net
    ;INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy
    ;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS

    io := DllCall("wininet\InternetOpen" . pFix
    , "Str", UserAgent ;lpszAgent
    , "UInt", AccessType
    , "Str", Proxy
    , "Str", ProxyBypass
    , "UInt", 0) ;dwFlags

    iou := DllCall("wininet\InternetOpenUrl" . pFix
    , "UInt", io
    , "Str", url
    , "Str", "" ;lpszHeaders
    , "UInt", 0 ;dwHeadersLength
    , "UInt", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item
    , "UInt", 0) ;dwContext

    If (ErrorLevel != 0 or iou = 0) {
        DllCall("FreeLibrary", "UInt", hModule)
        return 0
    }

    VarSetCapacity(buffer, 10240, 0)
    VarSetCapacity(BytesRead, 4, 0)

    Loop
    {
        ;http://msdn.microsoft.com/library/en-us/wininet/wininet/internetreadfile.asp
        irf := DllCall("wininet\InternetReadFile", "UInt", iou, "UInt", &buffer, "UInt", 10240, "UInt", &BytesRead)
        VarSetCapacity(buffer, -1) ;to update the variable's internally-stored length

        BytesRead_ = 0 ; reset
        Loop, 4  ; Build the integer by adding up its bytes. (From ExtractInteger-function)
            BytesRead_ += *(&BytesRead + A_Index-1) << 8*(A_Index-1) ;Bytes read in this very DllCall

        ; To ensure all data is retrieved, an application must continue to call the
        ; InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero.
        If (irf = 1 and BytesRead_ = 0)
            break
        Else ; append the buffer's contents
        {
            a_isunicode ? buffer:=StrGet(&buffer, "CP0")
            Result .= SubStr(buffer, 1, BytesRead_ * (a_isunicode ? 2 : 1))
        }

        /* optional: retrieve only a part of the file
        BytesReadTotal += BytesRead_
        If (BytesReadTotal >= 30000) ; only read the first x bytes
        break                      ; (will be a multiple of the buffer size, if the file is not smaller; trim if neccessary)
        */
    }

    DllCall("wininet\InternetCloseHandle",  "UInt", iou)
    DllCall("wininet\InternetCloseHandle",  "UInt", io)
    DllCall("FreeLibrary", "UInt", hModule)
   Return Result
}

JSON(ByRef js, s, v = "") {
   j = %js%
   Loop, Parse, s, .
   {
      p = 2
      RegExMatch(A_LoopField, "([+\-]?)([^[]+)((?:\[\d+\])*)", q)
      Loop {
         If (!p := RegExMatch(j, "(?<!\\)(""|')([^\1]+?)(?<!\\)(?-1)\s*:\s*((\{(?:[^{}]++|(?-1))*\})|(\[(?:[^[\]]++|(?-1))*\])|"
            . "(?<!\\)(""|')[^\7]*?(?<!\\)(?-1)|[+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:,|$|\})", x, p))
            Return
         Else If (x2 == q2 or q2 == "*") {
            j = %x3%
            z += p + StrLen(x2) - 2
            If (q3 != "" and InStr(j, "[") == 1) {
               StringTrimRight, q3, q3, 1
               Loop, Parse, q3, ], [
               {
                  z += 1 + RegExMatch(SubStr(j, 2, -1), "^(?:\s*((\[(?:[^[\]]++|(?-1))*\])|(\{(?:[^{\}]++|(?-1))*\})|[^,]*?)\s*(?:,|$)){" . SubStr(A_LoopField, 1) + 1 . "}", x)
                  j = %x1%
               }
            }
            Break
         }
         Else p += StrLen(x)
      }
   }
   If v !=
   {
      vs = "
      If (RegExMatch(v, "^\s*(?:""|')*\s*([+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:""|')*\s*$", vx)
         and (vx1 + 0 or vx1 == 0 or vx1 == "true" or vx1 == "false" or vx1 == "null" or vx1 == "nul"))
         vs := "", v := vx1
      StringReplace, v, v, ", \", All
      js := SubStr(js, 1, z := RegExMatch(js, ":\s*", zx, z) + StrLen(zx) - 1) . vs . v . vs . SubStr(js, z + StrLen(x3) + 1)
   }
   Return, j == "false" ? 0 : j == "true" ? 1 : j == "null" or j == "nul"
      ? "" : SubStr(j, 1, 1) == """" ? SubStr(j, 2, -1) : j
}

;-------------------------------------------------
; HTML encode/decode
;------------------------------------------------

StrPutVar(string, ByRef var, encoding)
{
    ; Ensure capacity.
    SizeInBytes := VarSetCapacity( var, StrPut(string, encoding)
        ; StrPut returns char count, but VarSetCapacity needs bytes.
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    ; Copy or convert the string.
    StrPut(string, &var, encoding)
   Return SizeInBytes 
}

UriEncode(str) 
{ 
   b_Format := A_FormatInteger 
   data := "" 
   SetFormat,Integer,H 
   SizeInBytes := StrPutVar(str,var,"utf-8")
   Loop, %SizeInBytes%
   {
   ch := NumGet(var,A_Index-1,"UChar")
   If (ch=0)
      Break
   if ((ch>0x7f) || (ch<0x30) || (ch=0x3d))
      s .= "%" . ((StrLen(c:=SubStr(ch,3))<2) ? "0" . c : c)
   Else
      s .= Chr(ch)
   }   
   SetFormat,Integer,%b_format% 
   return s 
} 


This code don't work!
;--------------------------------------------------
; Translate text using translate.google.com
; by Mikhail Kuropyatnikov (micdelt@mail.ru)
;
; Ctrl+C, Ctrl+C
;--------------------------------------------------
#NoEnv

DoublePress() ; Simulate double press
{
	static pressed1 = 0
	if pressed1 and A_TimeSincePriorHotkey <= 500
	{
		pressed1 = 0
		Translate("en","ru") ; from English to Russian
	}
	else
		pressed1 = 1
	
}

~^C:: DoublePress()

Translate(from,to)
{
	if clipboard =
		 return

	Transform, unicodeClipboard, Unicode 
	url := "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=" 
				. uriEncode(unicodeClipboard) . "&langpair=" . from . "%7C" . to 
				
	; simulate UrlDownloadToVAR
	UrlDownloadToFile, %url%, %A_ScriptDir%\translate.html
	FileRead, json_trans, %A_ScriptDir%\translate.html
	json_trans := UTF82Ansi(json_trans)

	rgxText = \Q{"translatedText":"\E(?P<Text>.*)\"\}
	rgxDetails = \Q"responseDetails": "\E(?P<Details>.*)\"\,
	rgxStatus = \Q"responseStatus": \E(?P<Status>\d*)

	RegExMatch(json_trans,rgxText,trans)
	RegExMatch(json_trans,rgxDetails,trans)
	RegExMatch(json_trans,rgxStatus,trans)

	if transStatus = 200
	{
		t := UnHTM(UnSlashUnicode(transText))
		; split long line to smaller lines about 40-50 symbols length
		t := RegExReplace(t,".{40,50}(\s)","$0`n")
		ToolTip %t%
		; copy result to clipboard
		Clipboard := t
	}
	else
		ToolTip %transDetails%
}

~LButton:: ; Remove tooltip left click
ToolTip
return

;---------------------------------------
; Convert strings
;---------------------------------------

/* 
CP_ACP   = 0 
CP_OEMCP = 1 
CP_MACCP = 2 
CP_UTF7  = 65000 
CP_UTF8  = 65001 
*/ 

Ansi2Oem(sString) 
{ 
   Ansi2Unicode(sString, wString, 0) 
   Unicode2Ansi(wString, zString, 1) 
   Return zString 
} 

Oem2Ansi(zString) 
{ 
   Ansi2Unicode(zString, wString, 1) 
   Unicode2Ansi(wString, sString, 0) 
   Return sString 
} 

Ansi2UTF8(sString) 
{ 
   Ansi2Unicode(sString, wString, 0) 
   Unicode2Ansi(wString, zString, 65001) 
   Return zString 
} 

UTF82Ansi(zString) 
{ 
   Ansi2Unicode(zString, wString, 65001) 
   Unicode2Ansi(wString, sString, 0) 
   Return sString 
} 

Ansi2Unicode(ByRef sString, ByRef wString, CP = 0) 
{ 
     nSize := DllCall("MultiByteToWideChar" 
      , "Uint", CP 
      , "Uint", 0 
      , "Uint", &sString 
      , "int",  -1 
      , "Uint", 0 
      , "int",  0) 

   VarSetCapacity(wString, nSize * 2) 

   DllCall("MultiByteToWideChar" 
      , "Uint", CP 
      , "Uint", 0 
      , "Uint", &sString 
      , "int",  -1 
      , "Uint", &wString 
      , "int",  nSize) 
} 

Unicode2Ansi(ByRef wString, ByRef sString, CP = 0) 
{ 
     nSize := DllCall("WideCharToMultiByte" 
      , "Uint", CP 
      , "Uint", 0 
      , "Uint", &wString 
      , "int",  -1 
      , "Uint", 0 
      , "int",  0 
      , "Uint", 0 
      , "Uint", 0) 

   VarSetCapacity(sString, nSize) 

   DllCall("WideCharToMultiByte" 
      , "Uint", CP 
      , "Uint", 0 
      , "Uint", &wString 
      , "int",  -1 
      , "str",  sString 
      , "int",  nSize 
      , "Uint", 0 
      , "Uint", 0) 
}

;-------------------------------------------------
; HTML encode/decode
;------------------------------------------------

UriEncode(str) 
{ ; v 0.3 / (w) 24.06.2008 by derRaphael / zLib-Style release 
   b_Format := A_FormatInteger 
   data := "" 
   SetFormat,Integer,H 
   Loop,Parse,str 
      if ((Asc(A_LoopField)>0x7f) || (Asc(A_LoopField)<0x30) || (asc(A_LoopField)=0x3d)) 
         data .= "%" . ((StrLen(c:=SubStr(ASC(A_LoopField),3))<2) ? "0" . c : c) 
      Else 
         data .= A_LoopField 
   SetFormat,Integer,%b_format% 
   return data 
} 

UriDecode(str) 
{ ; v 0.1 / (w) 28.06.2008 by derRaphael / zLib-Style release 
   Loop,Parse,str,`% 
      txt := (A_Index=1) ? A_LoopField : txt chr("0x" substr(A_LoopField,1,2)) SubStr(A_LoopField,3) 
   return txt 
}

UnHTM( HTM ) { ; Remove HTML formatting / Convert to ordinary text     by SKAN 19-Nov-2009 
 Static HT     ; Forum Topic: www.autohotkey.com/forum/topic51342.html 
 IfEqual,HT,,   SetEnv,HT, % "áaâa´?æ?àa&åaãa&au" 
 . "mla&bdquo„¦¦&bull•çc¸?¢?&circ?©©¤¤&dagger†&dagger‡°" 
 . "°÷?éeêeèeð?ëe&euro€&fnof?½?¼?¾?>>&h" 
 . "ellip…íiîi¡?ìi¿?ïi««&ldquo“&lsaquo‹&lsquo‘<<&m" 
 . "acr?&mdash—µµ··  &ndash–¬¬ñnóoôo&oelig?òo&or" 
 . "df?º?øoõoöo¶¶&permil‰±±£?"""»»&rdquo”®" 
 . "®&rsaquo›&rsquo’&sbquo‚&scarons§§­¹?²?³?ß?þ?&tilde?&tim" 
 . "es?&trade™úuûuùu¨?üuýy¥?ÿy" 
 TXT := RegExReplace( HTM,"<[^>]+>" )               ; Remove all tags between  "<" and ">" 
 Loop, Parse, TXT, &`;                              ; Create a list of special characters 
   L := "&" A_LoopField ";", R .= (!(A_Index&1)) ? ( (!InStr(R,L,1)) ? L:"" ) : "" 
 StringTrimRight, R, R, 1 
 Loop, Parse, R , `;                                ; Parse Special Characters 
  If F := InStr( HT, A_LoopField )                  ; Lookup HT Data 
    StringReplace, TXT,TXT, %A_LoopField%`;, % SubStr( HT,F+StrLen(A_LoopField), 1 ), All 
  Else If ( SubStr( A_LoopField,2,1)="#" ) 
    StringReplace, TXT, TXT, %A_LoopField%`;, % Chr(SubStr(A_LoopField,3)), All 
Return RegExReplace( TXT, "(^\s*|\s*$)")            ; Remove leading/trailing white spaces 
}

UnSlashUnicode(s)
{ 
  ; unslash unicode sequences like \u0026
  ; by Mikhail Kuropyatnikov 2009 (micdelt@mail.ru)
	rx = \\u([0-9a-fA-F]{4})
	pos = 0

	loop
	{
	pos := RegExMatch(s,rx,m,pos+1)
	if (pos = 0) 
		break
	StringReplace, s, s, %m%, % Chr("0x" . SubStr(m,3,4))
	}
	
	return s
}

add: fixed translation from chinese languages
update: works after API deprecation

micdelt
  • Members
  • 7 posts
  • Last active: Jul 01 2013 08:52 PM
  • Joined: 11 Dec 2009
Changed function Translate() to autodetect source language. Detected language code prefixes the translation.

Translate(to)
{
	if clipboard =
		 return

	Transform, unicodeClipboard, Unicode 
	url := "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=" 
				. uriEncode(unicodeClipboard) . "&langpair=%7C" . to 
				
	; simulate UrlDownloadToVAR
	UrlDownloadToFile, %url%, %A_ScriptDir%\translate.html
	FileRead, json_trans, %A_ScriptDir%\translate.html
	json_trans := UTF82Ansi(json_trans)

	rgxText = \Q{"translatedText":"\E(?P<Text>.*)\"\,
	rgxDetectedLanguage = \Q"detectedSourceLanguage":"\E(?P<DetectedLanguage>.*)\"\}
	rgxDetails = \Q"responseDetails": "\E(?P<Details>.*)\"\,
	rgxStatus = \Q"responseStatus": \E(?P<Status>\d*)

	RegExMatch(json_trans,rgxText,trans)
	RegExMatch(json_trans,rgxDetails,trans)
	RegExMatch(json_trans,rgxStatus,trans)
	RegExMatch(json_trans,rgxDetectedLanguage,trans)
	
	if transStatus = 200
	{
		t := UnHTM(UnSlashUnicode(transText))
		; split long line to smaller lines about 40-50 symbols length
		t := RegExReplace(t,".{40,50}(\s)","$0`n")
		if transDetectedLanguage = 
			ToolTip %t%
		else
			ToolTip %transDetectedLanguage%:%t%
	
		; copy result to clipboard
		Clipboard := t
	}
	else
		ToolTip %transDetails%
}


Tal Giladi
  • Guests
  • Last active:
  • Joined: --
Very useful!

oleg01
  • Members
  • 3 posts
  • Last active: Dec 21 2009 12:39 PM
  • Joined: 27 Nov 2009
Thank you very much for this script, it's really a must have for online translations.

I have a problem though, when I set it to translate to russian the displayed translation in the tooltip is a bunch of ????? (question marks). That's probably because my windows is not in russian. Could there be a way to fix this somehow? I havent' checked but I guess that for japanese or chinese it would happen the same.

Anyway it's great to have this script, absolutely one of my favorites.

ruespe
  • Members
  • 567 posts
  • Last active: Dec 20 2013 06:21 PM
  • Joined: 17 Jun 2008
Thanks a lot. Simple and very useful.

luetkmeyer
  • Members
  • 38 posts
  • Last active: Jul 01 2011 04:11 PM
  • Joined: 26 Feb 2010
Cool :D

RIST
  • Members
  • 39 posts
  • Last active: Aug 17 2012 08:36 PM
  • Joined: 08 May 2008
very nice script.. work with my tech mouse copy button (Y)

Gauss
  • Members
  • 203 posts
  • Last active: Jan 27 2012 12:49 PM
  • Joined: 10 Sep 2009
Thanks for this great script, I'm using it all the time, I also added this to it so it shows translation in big letters on a dark bachground:

Gui,+LastFound -border +AlwaysOnTop +ToolWindow -Caption
Gui,Color,black
Gui,Font, s20
Gui,Add,Text, x0 y0 cWhite vText,%clipboard%
GuiControlGet, text ,pos, text
X := ((A_ScreenWidth  - textW) / 2)
Y := ((A_ScreenHeight  - textH) / 2)
GuiControl, Move, text, x%x% y%Y% w%textW% h%textH%
Gui,Show, x0 y0 W%A_ScreenWidth% H%A_ScreenHeight%, ScreenMask325
WinSet, Transparent, 220, ScreenMask325
return

GuiEscape:
	Gui, Destroy
Return

I have 2 questions though:

-It doesn't retrieve translation if selected text is alittle too long, while the same size can be translated fine if done manually on Google.

-The second question is how to make it show translation in paragraphs with empty lines in between? just like when you do it manually.

Thanks again

Edit:
Now it shows translation in the middle

berban
  • Members
  • 200 posts
  • Last active: Oct 18 2014 03:22 PM
  • Joined: 30 Dec 2009
Nice! :D :D :D

micdelt
  • Members
  • 7 posts
  • Last active: Jul 01 2013 08:52 PM
  • Joined: 11 Dec 2009

Gauss It doesn't retrieve translation if selected text is alittle too long, while the same size can be translated fine if done manually on Google.


Text length is restricted by URL length. Full URL length must be less than about 2000 symbols. I made some tests, maximum length of text was about 1430 symbols.

Gauss
The second question is how to make it show translation in paragraphs with empty lines in between? just like when you do it manually.


This method can be used to translate small amount of text. But you can break text into paragraphs and translate it one by one calling this function for each paragraph. But will be difficult to show all the text in tooltip.

micdelt
  • Members
  • 7 posts
  • Last active: Jul 01 2013 08:52 PM
  • Joined: 11 Dec 2009
Some improvement.
1. If clipboard text is in language we want to translate to function translates text to anti language.
For example:
Translate("ru","en") - translates to russian, but if text already was in russian translates it to english.

2. Prefix shows translation direction "from>to", for example: "en>ru".

; translate to "to" language,
; if source language is "to" 
; translate to "anti" language

Translate(to,anti)
{
	use_anti = 0
	translate_to := to
	if clipboard = 
		 return

	Transform, unicodeClipboard, Unicode 
anti_translate:
	url := "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=" 
				. uriEncode(unicodeClipboard) . "&langpair=%7C" . translate_to
				
	; simulate UrlDownloadToVAR
	UrlDownloadToFile, %url%, %A_ScriptDir%\translate.html
	FileRead, json_trans, %A_ScriptDir%\translate.html
	json_trans := UTF82Ansi(json_trans)

	rgxText = \Q{"translatedText":"\E(?P<Text>.*)\"\,
	rgxDetectedLanguage = \Q"detectedSourceLanguage":"\E(?P<DetectedLanguage>.*)\"\}
	rgxDetails = \Q"responseDetails": "\E(?P<Details>.*)\"\,
	rgxStatus = \Q"responseStatus": \E(?P<Status>\d*)

	RegExMatch(json_trans,rgxText,trans)
	RegExMatch(json_trans,rgxDetails,trans)
	RegExMatch(json_trans,rgxStatus,trans)
	RegExMatch(json_trans,rgxDetectedLanguage,trans)
	
	if transStatus = 200
	{
		if (transDetectedLanguage = to and translate_to <> anti)
		{
			translate_to := anti
			goto anti_translate
		}
		
		t := UnHTM(UnSlashUnicode(transText))
		; split long line to smaller lines about 40-50 symbols length
		t := RegExReplace(t,".{40,50}(\s)","$0`n")
		if transDetectedLanguage = 
			ToolTip %t%
		else
		{
			ToolTip %transDetectedLanguage%>%translate_to%:%t%
		}
	
		; copy result to clipboard
		Clipboard := t
	}
	else
		ToolTip %transDetails%
}


ithion
  • Guests
  • Last active:
  • Joined: --
for lasy me or if u must compile it to give to friends or whatever:
add
To:
InputBox, to, ,Set language to translate to(default en=english):
if To :=""
Reload

InputBox, anti, ,Set language to translate from (default ru=russian):
if anti :=""
return

return

Just the fastet I could come up with.
Love This script.

Ithion
  • Guests
  • Last active:
  • Joined: --
Use this instead, includes needed change first funcion aswell

To:
InputBox, to, ,Set language to translate to(default en=english):
if To :=""
MsgBox You Failed, Restart script to try again

Anti:
InputBox, anti, ,Set language to translate to if the selected text already is in %to% (default ru=russian):,, 50px, 200px
if anti :=""
Goto, Anti
return

DoublePress() ; Simulate double press
{
   static pressed1 = 0
   if pressed1 and A_TimeSincePriorHotkey <= 500
   {
      pressed1 = 0
      Translate(to, anti) ; from English to Russian
   }
   else
      pressed1 = 1
   
}


Thanks!
  • Guests
  • Last active:
  • Joined: --
Thanks!
My wife is in health care and is using this to help speak overcome the language barrier at work.

Drini
  • Members
  • 6 posts
  • Last active: May 22 2011 11:39 AM
  • Joined: 21 Apr 2010
I realise that I (ithion) probably ****ed up in the last post.
Edit:
***UNBELIEVEBLE*** I FORGOT TO REMOVE A FEW VARS AND PUT GLOBAL IN A FUNC!!!!
Link goes to new exe that works
edited code below
:end edit:


I´ve been using this for awhile though and its very usefull when I'm playing with some brazilian friends e.g to explain what certain words mean.

New tested and working changes:
*user friendly inputboxes to set languages at each startup
*default languages is english and russian
*a few example language codes
*"restart tsl" reloads the script so you can pick two new languages.
*traytip and msgbox to give info to the user for easy sharing

.exe:
<!-- m -->http://www.autohotke.../translator.exe<!-- m -->
code:

;--------------------------------------------------
; Mikhail Kuropyatnikov (micdelt@mail.ru)
; traytip, inputboxes, default languages,restart, and msgbox alert added by drini(ydrini@twitter.com aka ithion) to make it more user friendly
; 
;
; 
;--------------------------------------------------
#NoEnv
Traytip,Translator, Translate text using translate.google.com `n use Ctrl+c `, Ctrl+C ( thats ctrl+c twice you fellows) to translate,5,1

;~ To:
InputBox, to,Translator,Set language to translate to `n by Mikhail Kuropyatnikov (micdelt@mail.ru) `n modified by Drini(yDrini@twitter.com) `n default is en(english) `n examples: Sv=Swedish De=German Pt = Portuguese Es=Spanish Ru=Russian
;set default if needed
if to =
to = en

;~ Anti:
InputBox, anti,Translator,Set language to translate to if the selected text already is in "%to%" `n by Mikhail Kuropyatnikov (micdelt@mail.ru) `n modified by Drini(yDrini@twitter.com) `n default is ru(russian) in respect to the original creator`n examples: Sv=Swedish De=German Pt = Portuguese Es=Spanish Ru=Russian
;set default if needed
if anti =
anti = ru

;alert user 
MsgBox Language to translate to was set to "%to%" and if text is in "%to%" it will be translated to "%anti%" `n type "restart tsl" or rightclick the tray icon to choose new languages

DoublePress() ; Simulate double press
{
   global
   static pressed1 = 0
   if pressed1 and A_TimeSincePriorHotkey <= 500
   {
      pressed1 = 0
      Translate(to, anti) ; from English to Russian
   }
   else
      pressed1 = 1
   
}

::restart tsl::
Reload
Return
~^C:: DoublePress()

; translate to "to" language,
; if source language is "to"
; translate to "anti" language

Translate(to,anti)
{

   use_anti = 0
   translate_to := to
   if clipboard =
       return

   Transform, unicodeClipboard, Unicode
anti_translate:
   url := "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q="
            . uriEncode(unicodeClipboard) . "&langpair=%7C" . translate_to
            
   ; simulate UrlDownloadToVAR
   UrlDownloadToFile, %url%, %A_ScriptDir%\translate.html
   FileRead, json_trans, %A_ScriptDir%\translate.html
   json_trans := UTF82Ansi(json_trans)

   rgxText = \Q{"translatedText":"\E(?P<Text>.*)\"\,
   rgxDetectedLanguage = \Q"detectedSourceLanguage":"\E(?P<DetectedLanguage>.*)\"\}
   rgxDetails = \Q"responseDetails": "\E(?P<Details>.*)\"\,
   rgxStatus = \Q"responseStatus": \E(?P<Status>\d*)

   RegExMatch(json_trans,rgxText,trans)
   RegExMatch(json_trans,rgxDetails,trans)
   RegExMatch(json_trans,rgxStatus,trans)
   RegExMatch(json_trans,rgxDetectedLanguage,trans)
   
   if transStatus = 200
   {
      if (transDetectedLanguage = to and translate_to <> anti)
      {
         translate_to := anti
         goto anti_translate
      }
      
      t := UnHTM(UnSlashUnicode(transText))
      ; split long line to smaller lines about 40-50 symbols length
      t := RegExReplace(t,".{40,50}(\s)","$0`n")
      if transDetectedLanguage =
         ToolTip %t%
      else
      {
         ToolTip %transDetectedLanguage%>%translate_to%:%t%
      }
   
      ; copy result to clipboard
      Clipboard := t
   }
   else
      ToolTip %transDetails%
}
~LButton:: ; Remove tooltip left click
ToolTip
return

;---------------------------------------
; Convert strings
;---------------------------------------

/*
CP_ACP   = 0
CP_OEMCP = 1
CP_MACCP = 2
CP_UTF7  = 65000
CP_UTF8  = 65001
*/

Ansi2Oem(sString)
{
   Ansi2Unicode(sString, wString, 0)
   Unicode2Ansi(wString, zString, 1)
   Return zString
}

Oem2Ansi(zString)
{
   Ansi2Unicode(zString, wString, 1)
   Unicode2Ansi(wString, sString, 0)
   Return sString
}

Ansi2UTF8(sString)
{
   Ansi2Unicode(sString, wString, 0)
   Unicode2Ansi(wString, zString, 65001)
   Return zString
}

UTF82Ansi(zString)
{
   Ansi2Unicode(zString, wString, 65001)
   Unicode2Ansi(wString, sString, 0)
   Return sString
}

Ansi2Unicode(ByRef sString, ByRef wString, CP = 0)
{
     nSize := DllCall("MultiByteToWideChar"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &sString
      , "int",  -1
      , "Uint", 0
      , "int",  0)

   VarSetCapacity(wString, nSize * 2)

   DllCall("MultiByteToWideChar"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &sString
      , "int",  -1
      , "Uint", &wString
      , "int",  nSize)
}

Unicode2Ansi(ByRef wString, ByRef sString, CP = 0)
{
     nSize := DllCall("WideCharToMultiByte"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &wString
      , "int",  -1
      , "Uint", 0
      , "int",  0
      , "Uint", 0
      , "Uint", 0)

   VarSetCapacity(sString, nSize)

   DllCall("WideCharToMultiByte"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &wString
      , "int",  -1
      , "str",  sString
      , "int",  nSize
      , "Uint", 0
      , "Uint", 0)
}

;-------------------------------------------------
; HTML encode/decode
;------------------------------------------------

UriEncode(str)
{ ; v 0.3 / (w) 24.06.2008 by derRaphael / zLib-Style release
   b_Format := A_FormatInteger
   data := ""
   SetFormat,Integer,H
   Loop,Parse,str
      if ((Asc(A_LoopField)>0x7f) || (Asc(A_LoopField)<0x30) || (asc(A_LoopField)=0x3d))
         data .= "%" . ((StrLen(c:=SubStr(ASC(A_LoopField),3))<2) ? "0" . c : c)
      Else
         data .= A_LoopField
   SetFormat,Integer,%b_format%
   return data
}

UriDecode(str)
{ ; v 0.1 / (w) 28.06.2008 by derRaphael / zLib-Style release
   Loop,Parse,str,`%
      txt := (A_Index=1) ? A_LoopField : txt chr("0x" substr(A_LoopField,1,2)) SubStr(A_LoopField,3)
   return txt
}

UnHTM( HTM ) { ; Remove HTML formatting / Convert to ordinary text     by SKAN 19-Nov-2009
 Static HT     ; Forum Topic: www.autohotkey.com/forum/topic51342.html
 IfEqual,HT,,   SetEnv,HT, % "áaâa´?æ?àa&åaãa&au"
 . "mla&bdquo„¦¦&bull•çc¸?¢?&circ?©©¤¤&dagger†&dagger‡°"
 . "°÷?éeêeèeð?ëe&euro€&fnof?½?¼?¾?>>&h"
 . "ellip…íiîi¡?ìi¿?ïi««&ldquo“&lsaquo‹&lsquo‘<<&m"
 . "acr?&mdash—µµ··  &ndash–¬¬ñnóoôo&oelig?òo&or"
 . "df?º?øoõoöo¶¶&permil‰±±£?"""»»&rdquo”®"
 . "®&rsaquo›&rsquo’&sbquo‚&scarons§§­¹?²?³?ß?þ?&tilde?&tim"
 . "es?&trade™úuûuùu¨?üuýy¥?ÿy"
 TXT := RegExReplace( HTM,"<[^>]+>" )               ; Remove all tags between  "<" and ">"
 Loop, Parse, TXT, &`;                              ; Create a list of special characters
   L := "&" A_LoopField ";", R .= (!(A_Index&1)) ? ( (!InStr(R,L,1)) ? L:"" ) : ""
 StringTrimRight, R, R, 1
 Loop, Parse, R , `;                                ; Parse Special Characters
  If F := InStr( HT, A_LoopField )                  ; Lookup HT Data
    StringReplace, TXT,TXT, %A_LoopField%`;, % SubStr( HT,F+StrLen(A_LoopField), 1 ), All
  Else If ( SubStr( A_LoopField,2,1)="#" )
    StringReplace, TXT, TXT, %A_LoopField%`;, % Chr(SubStr(A_LoopField,3)), All
Return RegExReplace( TXT, "(^\s*|\s*$)")            ; Remove leading/trailing white spaces
}

UnSlashUnicode(s)
{
;~   ; unslash unicode sequences like \u0026
  ; by Mikhail Kuropyatnikov 2009 (micdelt@mail.ru)
   rx = \\u([0-9a-fA-F]{4})
   pos = 0

   loop
   {
   pos := RegExMatch(s,rx,m,pos+1)
   if (pos = 0)
      break
   StringReplace, s, s, %m%, % Chr("0x" . SubStr(m,3,4))
   }
   
   return s
}