Translation hotkey

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
roysubs
Posts: 428
Joined: 29 Sep 2018, 16:37

Translation hotkey

22 Apr 2024, 23:55

I really want a hotkey that can take a piece of currently selected text and translate it, either with an autohotkey dialogue that calls an external translator API, or by passing the text to a separate translator app. This seems like it should be a fairly common thing that folk have done, can anyone point me to such a solution please?
roysubs
Posts: 428
Joined: 29 Sep 2018, 16:37

Re: Translation hotkey

23 Apr 2024, 02:45

Thanks, I'll do some more searches on the forum then. I was curious if there are other well known repositories for Autohotkey scripts, or do you think just search here, 99% of things are in this forum?

I see you are using AHK v2 in the script you were helping someone with German translation. Have you moved all your work over to v2 now? I'd like to, but I don't really understand the differences to be able to translate my v1 over to v2, any tips on where to start with that? As I have v1 engine installed on my system, I can't run your v2 script, or, is it possible to run a v2 script side by side with a v1 script?

I'll use the script you were helping on the German translator as a starting point, this looks to do pretty much exactly what I am after so will adjust for my needs, thanks.
User avatar
mikeyww
Posts: 28873
Joined: 09 Sep 2014, 18:38

Re: Translation hotkey

23 Apr 2024, 06:31

The "Scripts and Functions" boards contain additional working scripts of many kinds.

viewforum.php?f=6

viewforum.php?f=83

You can have both versions, v1 and v2, installed and then run scripts of either version. I write new scripts in v2. I translated a few of my older v1 scripts, but not all, so I still run a bunch of v1 scripts. I recommend writing all new scripts in v2 unless you have a specific reason to use v1. One reason could be including an external v1 library.

Differences between v1 and v2

To run a v2 script, first install AutoHotkey v2. The installer will leave your v1 program intact.
RussF
Posts: 1440
Joined: 05 Aug 2021, 06:36

Re: Translation hotkey

23 Apr 2024, 06:50

I created the following script based on a function by @teadrinker to access Google translate. My wife needed something to translate her weekly newsletter for the non-English speaking parents of some of her students. It's currently set up to translate English to Spanish, but is easily modified - just look at the comments.

It works by highlighting the text you wish to translate, pressing Ctrl-Alt-t and the text is replaced with the translated text. Ctrl-Alt-Shift-t will exit the script. You can change these keys to anything you would like.

This is a single purpose script that does just what we needed at the time. It's written in V1 and I never had the need to translate to V2, because it just works. Others have created scripts with GUIs allowing you to select the languages and other embellishments. That may be more of what you are looking for, I don't know.

Code: Select all

; Adapted from @teadrinker's script found at
; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=63835&hilit=google+translate

/*
Language codes:
auto_Automatic
nl_Nederlands
af_Suid-Afrika
fy_Fryslân
eu_Basque
ca_Catalan
de_Deutsch
da_Dansk
sv_Sverige
no_Norge
is_Iceland
fi_Suomen
en_English
pt_Portugues
es_Español
it_Italia
fr_Français
ru_Rossija
zh-CN_Chinese
ja_Nippon
ko_Korea
ro_Romania
bg_Bulgaria
mc_Macedonia
el_Greek
tr_Turkiye
sq_Albania
hr_Croatia
sr_Serbia
sl_Slovenia
hu_Hungary
cs_Czech
sk_Slovakia
pl_Poland
be_Belarus
uk_Ukraina
et_Estonia
lv_Latvija
lt_Lituania
az_Azerbaijan 
ka_Georgian
ar_Arabic
iw_Hebrew
hi_Hindi
id_Indonesia
ms_Malaysia
vi_Vietnam
th_Thai
ta_Tamil
ur_Urdu
sw_Swahili
*/

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#Requires AutoHotkey v1.1.33+

Tooltip, % "English -> Spanish Translator`n<Ctrl><Alt>t to Activate`n<Ctrl><Alt><Shift>t to Exit"
Sleep 5000
Tooltip

^!t::
   clipboard := ""
   Sleep 100
   Send ^c
   ClipWait, 1
   TextToXlate := clipboard
   If TextToXlate {
      clipboard := ""
      Translated := GoogleTranslate(TextToXlate, "en", "es") ; use codes from table above for different languages
      Translated := RegExReplace(Translated, "s)\R\+.+")
      clipboard := Translated
      ClipWait, 1
      Send ^v
   }
   Else MsgBox, Nothing to translate!
Return

^!+t::
   Tooltip, % "Translator exiting..."
   Sleep 3000
   Tooltip
Exitapp


GoogleTranslate(str, from := "auto", to := "en") {
   static JS := CreateScriptObj(), _ := JS.( GetJScript() ) := JS.("delete ActiveXObject; delete GetObject;")
   
   json := SendRequest(JS, str, to, from, proxy := "")
   oJSON := JS.("(" . json . ")")

   if !IsObject(oJSON[1]) {
      Loop % oJSON[0].length
         trans .= oJSON[0][A_Index - 1][0]
   }
   else {
      MainTransText := oJSON[0][0][0]
      Loop % oJSON[1].length {
         trans .= "`n+"
         obj := oJSON[1][A_Index-1][1]
         Loop % obj.length {
            txt := obj[A_Index - 1]
            trans .= (MainTransText = txt ? "" : "`n" txt)
         }
      }
   }
   if !IsObject(oJSON[1])
      MainTransText := trans := Trim(trans, ",+`n ")
   else
      trans := MainTransText . "`n+`n" . Trim(trans, ",+`n ")

   from := oJSON[2]
   trans := Trim(trans, ",+`n ")
   Return trans
}

SendRequest(JS, str, tl, sl, proxy) {
   static http
   ComObjError(false)
   if !http
   {
      http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
      ( proxy && http.SetProxy(2, proxy) )
      http.open("GET", "https://translate.google.com", true)
      http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
      http.send()
      http.WaitForResponse(-1)
   }
   http.open("POST", "https://translate.googleapis.com/translate_a/single?client=gtx"
                ; or "https://clients5.google.com/translate_a/t?client=dict-chrome-ex"
      . "&sl=" . sl . "&tl=" . tl . "&hl=" . tl
      . "&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=0&ssel=0&tsel=0&pc=1&kc=1"
      . "&tk=" . JS.("tk").(str), true)

   http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
   http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
   http.send("q=" . URIEncode(str))
   http.WaitForResponse(-1)
   Return http.responsetext
}

URIEncode(str, encoding := "UTF-8")  {
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)

   while code := NumGet(Var, A_Index - 1, "UChar")  {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)
      UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
   }
   Return UrlStr
}

GetJScript()
{
   script =
   (
      var TKK = ((function() {
        var a = 561666268;
        var b = 1526272306;
        return 406398 + '.' + (a + b);
      })());

      function b(a, b) {
        for (var d = 0; d < b.length - 2; d += 3) {
            var c = b.charAt(d + 2),
                c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c),
                c = "+" == b.charAt(d + 1) ? a >>> c : a << c;
            a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c
        }
        return a
      }

      function tk(a) {
          for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
              var c = a.charCodeAt(f);
              128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
              (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240,
              g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
          }
          a = h;
          for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6");
          a = b(a, "+-3^+b+-f");
          a ^= Number(e[1]) || 0;
          0 > a && (a = (a & 2147483647) + 2147483648);
          a `%= 1E6;
          return a.toString() + "." + (a ^ h)
      }
   )
   Return script
}

CreateScriptObj() {
   static doc, JS, _JS
   if !doc {
      doc := ComObjCreate("htmlfile")
      doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
      JS := doc.parentWindow
      if (doc.documentMode < 9)
         JS.execScript()
      _JS := ObjBindMethod(JS, "eval")
   }
   Return _JS
}
Russ
User avatar
Chunjee
Posts: 1589
Joined: 18 Apr 2014, 19:05
Contact:

Re: Translation hotkey

23 Apr 2024, 07:37

I like the DeepL API. it is free if you keep your translations under {{x}} per month.


Here is a simple one I saw once for looking up singular words on Jisho.org

Code: Select all

!j::
run, %comspec% /c start https://jisho.org/search/%clipboard%
return

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 63 guests