; Configuration #singleinstance force fileencoding, utf-8 settitlematchmode, 3 stringcasesense, on ; Initialization ascii_to_unicode := comobjcreate("Scripting.Dictionary") html_to_unicode := comobjcreate("Scripting.Dictionary") pattern_to_unicode := comobjcreate("Scripting.Dictionary") lower_to_upper := comobjcreate("Scripting.Dictionary") unicode_to_ascii := comobjcreate("Scripting.Dictionary") ; Load load_dictionary("Text.csv") ; Include guard goto, 70fabbc9-4cfb-443b-aca6-5434ebef765f ; Include guard if (not (isfunc("ascii_to_unicode"))) { ; Convert ASCII to Unicode ascii_to_unicode(text) { global ascii_to_unicode for ascii in ascii_to_unicode { unicode := ascii_to_unicode.item(ascii) stringreplace, text, text, %ascii%, %unicode%, all } global pattern_to_unicode for pattern in pattern_to_unicode { text := regexreplace(text, pattern, pattern_to_unicode.item(pattern)) } return html_to_unicode(text) } } ; Include guard if (not (isfunc("find_file"))) { ; Find a file in AutoHotkey path find_file(name) { ; Check the file if (not ( fileexist(file := A_ScriptDir . "\" . name) or fileexist(file := A_WorkingDir . "\" . name))) { ; Debug msgbox, 0, File not found, "%name%"`n`nA_ScriptDir`t"%A_ScriptDir%"`nA_WorkingDir`t"%A_WorkingDir%" return } return file } } ; Include guard if (not (isfunc("first_to_upper"))) { ; Convert first character to upper case first_to_upper(text) { global lower_to_upper letter := substr(text, 1, 1) if ("" == lower_to_upper.item(letter)) { code := asc(letter) if ((97 <= code) and (code <= 122)) { letter := chr(code - 32) } } else { letter := lower_to_upper.item(letter) } return letter . substr(text, 2) } } ; Include guard if (not (isfunc("html_to_unicode"))) { ; Convert HTML to Unicode html_to_unicode(text) { global html_to_unicode position := 1 while (not (0 == (position := regexmatch(text, "&([^;]+);", entity, position)))) { length := strlen(entity) if (regexmatch(entity1, "^#([1-9][0-9]*)$", numeric)) { replace := chr(numeric1) } else if (regexmatch(entity1, "^#x([1-9a-fA-F][0-9a-fA-F]*)$", numeric)) { format := A_FormatInteger setformat, integer, dec numeric = 0x%numeric1% numeric += 0 setformat, integer, %format% replace := chr(numeric) } else { replace := html_to_unicode.item(entity1) } if ("" == replace) { ++position } else { text := substr(text, 1, position - 1) . replace . substr(text, position + length) position += strlen(replace) } } return text } } ; Include guard if (not (isfunc("is_ascii"))) { ; Test text form ASCII is_ascii(text) { loop, parse, text { if (127 < asc(A_LoopField)) { return false } } return true } } ; Include guard if (not (isfunc("load_dictionary"))) { ; Load dictionary file load_dictionary(name) { file := find_file(name) global ascii_to_unicode, html_to_unicode, lower_to_upper, pattern_to_unicode, unicode_to_ascii loop, read, %file% { if ("//" == substr(trim(A_LoopReadLine), 1, 2)) { ; Ignore comment } else if ("" == A_LoopReadLine) { type := } else if ("" == type) { type := A_LoopReadLine if (not (("emoticon" == type) or ("html" == type) or ("name" == type) or ("regex" == type) or ("string" == type) or ("test" == type) or ("unicode" == type) or ("upper" == type) or ("word" == type))) { msgbox, 0, Malformed dictionary, Unknown type "%type%" on line %A_Index%. return } } else { first := loop, parse, A_LoopReadLine, csv { cell := html_to_unicode(A_LoopField) if ("" == first) { first := cell if ("name" == type) { load_pattern(first, first) } else if ("word" == type) { load_pattern(first, first) upper := first_to_upper(first) load_pattern(upper, upper) } } else if ("emoticon" == type) { emoticon = :%cell%: pattern = \B%emoticon%\B pattern_to_unicode.item(pattern) := first unicode_to_ascii.item(first) := emoticon } else if ("html" == type) { html_to_unicode.item(A_LoopField) := chr(first) } else if (("name" == type) or ("word" == type)) { load_pattern(cell, first) load_pattern(first_to_upper(cell), first_to_upper(first)) } else if ("regex" == type) { pattern_to_unicode.item(cell) := first } else if ("string" == type) { ascii_to_unicode.item(A_LoopField) := first unicode_to_ascii.item(first) := A_LoopField } else if ("test" == type) { load_test(cell, first) } else if ("unicode" == type) { unicode_to_ascii.item(cell) := first } else if ("upper" == type) { lower_to_upper.item(cell) := first } } } } } } ; Include guard if (not (isfunc("load_pattern"))) { ; Load a ASCII or Unicode regex pattern load_pattern(source, target) { global unicode_to_ascii for unicode in unicode_to_ascii { ascii := unicode_to_ascii.item(unicode) if (2 == strlen(ascii) + strlen(unicode)) { stringreplace, source, source, %unicode%, [%ascii%%unicode%], all } else { stringreplace, source, source, %unicode%, (?:%ascii%|%unicode%), all } } if (not (source == target)) { source = (*UCP)\b%source%\b global pattern_to_unicode pattern_to_unicode.item(source) := target } } } ; Include guard if (not (isfunc("load_test"))) { ; Test ASCII or HTML to Unicode load_test(source, target) { result := ascii_to_unicode(source) reverse := unicode_to_ascii(result) if (not ((result == target) and is_ascii(reverse) and (ascii_to_unicode(reverse) == target))) { source_length := strlen(A_LoopField) source_encode := split_to_code(A_LoopField) target_length := strlen(target) target_encode := split_to_code(target) result_length := strlen(result) result_encode := split_to_code(result) reverse_length := strlen(reverse) reverse_encode := split_to_code(reverse) msgbox, 0, Test failed, Source`t# %source_length%`t"%source%"`n%source_encode%`n`nTarget`t# %target_length%`t"%target%"`n%target_encode%`n`nResult`t# %result_length%`t"%result%"`n%result_encode%`n`nReverse`t# %reverse_length%`t"%reverse%"`n%reverse_encode% } } } ; Include guard if (not (isfunc("send_key"))) { ; Send key and restore state send_key(text) { ; Save key state if ("1" == getkeystate("lctrl")) { status := status . "{lctrl}" } if ("1" == getkeystate("rctrl")) { status := status . "{rctrl}" } if ("1" == getkeystate("lalt")) { status := status . "{lalt}" } if ("1" == getkeystate("ralt")) { status := status . "{ralt}" } if ("1" == getkeystate("lshift")) { status := status . "{lshift}" } if ("1" == getkeystate("rshift")) { status := status . "{rshift}" } ; Send key send, {lctrl up}{rctrl up}{lalt up}{ralt up}{lshift up}{rshift up} send, %text% send, {lctrl up}{rctrl up}{lalt up}{ralt up}{lshift up}{rshift up} ; Restore key state send, %status% } } ; Include guard if (not (isfunc("split_to_code"))) { ; Convert text to code point list split_to_code(text) { loop, parse, text { if ("" == code) { code := asc(A_LoopField) } else { code := code . " " . asc(A_LoopField) } } return code } } ; Include guard if (not (isfunc("text"))) { ; Process input line text(encoding) { ; Check window wingetclass, class, a wingettitle, title, a winget, process, ProcessName, %title% if (false ; Explorer or (("explorer.exe" == process) and ("CabinetWClass" == class)) ; MadEdit, without opened file or (("MadEdit.exe" == process) and ("wxWindowClassNR" == class) and ("MadEdit " == title)) or false) { ; Ignore return } else if (false ; Chrome or (("chrome.exe" == process) and ("Chrome_WidgetWin_1" == class) and regexmatch(title, " - Google Chrome$")) ; Comic Collector or (("" == process) and (("TfmComic" == class) and (( regexmatch(title, "^Add Comic ") or regexmatch(title, "^Edit Comic: ") or regexmatch(title, "^Edit Multiple Comics"))) or (("TfmSeriesLookupItem" == class) and ("Edit Series" == title)) or (("TfmSortLookupItem" == class) and ("Edit Location" == title)))) ; Dota 2 or (("dota.exe" == process) and ("Valve001" == class) and ("DOTA 2" == title)) ; Dota 2 Reborn or (("dota2.exe" == process) and ("SDL_app" == class) and ("Dota 2" == title)) ; Internet Explorer or (("IEXPLORE.EXE" == process) and ("IEFrame" == class) and regexmatch(title, " - Internet Explorer$")) ; Keepass or (("KeePass.exe" == process) and ("#32770" == class) and (("Add Entry" == title) or ("Add Group" == title) or ("Edit Entry" == title) or ("Save as Profile" == title))) ; Libre Office or (("soffice.bin" == process) and ("SALFRAME" == class) and regexmatch(title, " - LibreOffice Writer$")) ; Line or (("line.exe" == process) and ("Qt5QWindowIcon" == class) and ("LINE" == title)) ; MadEdit, with opened file or (("MadEdit.exe" == process) and ("wxWindowClassNR" == class) and regexmatch(title, "^MadEdit - \[.+\] $")) ; mIRC or (("mirc.exe" == process) and ("mIRC" == class) and regexmatch(title, "^mIRC - ")) ; Movie Collector or (("" == process) and ("TfmMovie" == class) and regexmatch(title, "^Edit Movie: ")) ; MP3tag or (("Mp3tag.exe" == process) and ("Afx:00400000:b:00010005:00000006:0FC00909" == class) and regexmatch(title, "^Mp3tag v2\.72 - ")) ; Notepad or ((("notepad.exe" == process) or ("NOTEPAD.EXE" == process)) and ((("Notepad" == class) and regexmatch(title, " - Notepad$")) or (("#32770" == class) and ("Find" == title)))) ; RetroShare or (("RetroShare.exe" == process) and ("QWidget" == class) and regexmatch(title, "^RetroShare [0-9]\.[0-9]\.[0-9]x ")) ; Run or (("Explorer.EXE" == process) and ("#32770" == class) and ("Run" == title)) or false) { ; Continue } else if (false ; Samsung Scan Assistant or (("SAProc.exe" == process) and ("#32770" == class) and ("Save" == title)) ; Skype or (("Skype.exe" == process) and ("tSkMainForm" == class) and regexmatch(title, html_to_unicode("^Skype™"))) ; Spotify or (("Spotify.exe" == process) and ("SpotifyMainWindow" == class) and (("Spotify" == title) or regexmatch(title, " - "))) ; StarCraft 2 or (("" == process) and ("StarCraft II" == class) and ("StarCraft II" == title)) ; Steam or (("Steam.exe" == process) and (("USurface_3873329" == class) or ("USurface_78552928" == class)) and (("Steam" == title) or regexmatch(title, "^Friends - "))) ; TeamSpeak or (("ts3client_win64.exe" == process) and ("Qt5QWindowIcon" == class) and ("Contacts" == title)) ; Tortoise Hg or (("thgw.exe" == process) and ("QWidget" == class) and regexmatch(title, " - TortoiseHg Workbench - ")) ; Tortoise SVN or (("TortoiseProc.exe" == process) and ("#32770" == class) and regexmatch(title, " - Commit - TortoiseSVN$")) ; Trillian or (("trillian.exe" == process) and (("icoIRC" == class) or ("icoYahoo" == class)) ; Windows Apps or (("ApplicationFrameHost.exe" == process) and ("ApplicationFrameWindow" == class) ; Windows Apps, Edge and (regexmatch(title, html_to_unicode(" ‎- Microsoft Edge$")) ; Windows Apps, Facebook Messenger or ("Messenger" == title) ; Windows Apps, Line or ("LINE" == title) ; Windows Apps, Skype or ("Skype" == title)))) or false) { ; Continue } else { ; Debug msgbox, 0, Unknown window, Process`t"%process%"`nClass`t"%class%"`nTitle`t"%title%" return } ; Read line previous := clipboard clipboard := send_key("{shift down}{home}{shift up}{ctrl down}c{ctrl up}") clipwait, 5 ; Replace content if ("ascii" == encoding) { clipboard := unicode_to_ascii(clipboard) } else if ("unicode" == encoding) { clipboard := ascii_to_unicode(clipboard) } else { ; Debug msgbox, 0, Unknown encoding, Encoding`t"%encoding%" return } ; Write line send_key("{ctrl down}v{ctrl up}") clipboard := previous } } ; Include guard if (not (isfunc("unicode_to_ascii"))) { ; Convert Unicode to ASCII unicode_to_ascii(text) { global unicode_to_ascii for unicode in unicode_to_ascii { ascii := unicode_to_ascii.item(unicode) stringreplace, text, text, %unicode%, %ascii%, all } return text } } ; Ctrl + Space ^space:: { text("unicode") } return ; Ctrl + Shift + Space ^+space:: { text("ascii") } return ; Include guard 70fabbc9-4cfb-443b-aca6-5434ebef765f: