How to properly parse spanish, portuguese, french, etc from RunWaitOne/CMD/WshShell/ComSpec Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
HenriAug
Posts: 14
Joined: 10 May 2017, 18:16

How to properly parse spanish, portuguese, french, etc from RunWaitOne/CMD/WshShell/ComSpec

Post by HenriAug » 04 Jul 2022, 10:40

Hi!

What I'm trying to do

I'm automating my git work with Sublime Merge.
Luckily, that software puts the whole path to the git repo in the win title.
So I can parse it and run some git commands.

One Hotkey runs

Code: Select all

git status -s
through RunWaitOne to get all modified files. Then it shows a listbox where i can pick one of those files and AHK will type the filename for me inside the commit message.
CmdPalette.png
CmdPalette.png (39 KiB) Viewed 246 times
The Code

Code: Select all

#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.

; Source
; https://www.autohotkey.com/docs/commands/Run.htm#StdOut
RunWaitOne(command, workingDir="") {
    ; WshShell object: http://msdn.microsoft.com/en-us/library/aew9yb99
    shell := ComObjCreate("WScript.Shell")

    if(workingDir != ""){
      ; gets the original CurrentDirectory and
      ; sets the new one
      originalCurrDir := shell.CurrentDirectory
      shell.CurrentDirectory := workingDir
    }

    ; Execute a single command via cmd.exe
    exec := shell.Exec(ComSpec " /C" command)
    ; Read and return the command's output

    if(workingDir != ""){
      ; reset the original current directory otherwise
      ; the %WorkingDir% for the current AHK process would
      ; also change!
      shell.CurrentDirectory := originalCurrDir
    }
    readAll := exec.StdOut.ReadAll()
    out := []
    Loop, Parse, readAll, `n
    {
      out.Push( A_loopField )
    }

    return ArrayJoin(out, "`n")
}

;https://www.autohotkey.com/boards/viewtopic.php?t=7124
ArrayJoin(arr, separator:=",", printIndex:=False){
    str := ""
    for index,el in arr {
        if(printIndex){
            str .= "[" . index . "]"
        }
        str .= el . separator
    }
    return SubStr(str, 1, -StrLen(separator))
}

; result := RunWaitOne("dir /B", A_WorkingDir)
result := RunWaitOne("git status -s", A_WorkingDir)

MsgBox, % result
The Problem

My repositories are in portuguese, spanish, french, etc and I want to be able to deal with all kinds of characters, but a lot of them are appearing as

Code: Select all

\303\[3 digits]
See the following image:
MsgBox Example.png
MsgBox Example.png (19.86 KiB) Viewed 246 times
My AHK installation is UNICODE, btw.

What I've tried

I've tried a lot of different things, including looping through the lines and using StrReplace like:

Code: Select all

StrReplace(A_LoopField, "\303\243", "ã")
Looping through the chars with Loop, Parse and using NumGet/NumPut.

Tried StrGet/StrPut.

I feel I'm missing something very simple.

How to test

I've attached a zip file containing a MVE repository. You just need to execute the .ahk script on it. Of course, you need git on your PATH :)
Attachments
RunWait CMD Encoding Test.zip
(22.52 KiB) Downloaded 7 times

HenriAug
Posts: 14
Joined: 10 May 2017, 18:16

Re: How to properly parse spanish, portuguese, french, etc from RunWaitOne/CMD/WshShell/ComSpec  Topic is solved

Post by HenriAug » 04 Jul 2022, 11:23

I've found out why StrReplace was not working. I had to save my files as UTF-8 with BOM in order to the replacing characters to be encoded properly.

In the end the code was something like that:

Code: Select all

; SOURCE:
; https://www.autohotkey.com/docs/commands/Run.htm#StdOut
RunWaitOne(command, workingDir="") {
    ; WshShell object: http://msdn.microsoft.com/en-us/library/aew9yb99
    shell := ComObjCreate("WScript.Shell")

    if(workingDir != ""){
      ; gets the original CurrentDirectory and
      ; sets the new one
      originalCurrDir := shell.CurrentDirectory
      shell.CurrentDirectory := workingDir
    }

    ; Execute a single command via cmd.exe
    exec := shell.Exec(ComSpec " /C" command)
    ; Read and return the command's output

    if(workingDir != ""){
      ; reset the original current directory otherwise
      ; the %WorkingDir% for the current AHK process would
      ; also change!
      shell.CurrentDirectory := originalCurrDir
    }
    readAll := exec.StdOut.ReadAll()
    out := []
    Loop, Parse, readAll, `n
    {
      out.Push( fixStringFromComSpec(A_loopField) )
    }
    return ArrayJoin(out, "`n")
}

;https://www.autohotkey.com/boards/viewtopic.php?t=7124
ArrayJoin(arr, separator:=",", printIndex:=False){
    str := ""
    for index,el in arr {
        if(printIndex){
            str .= "[" . index . "]"
        }
        str .= el . separator
    }
    return SubStr(str, 1, -StrLen(separator))
}

; THE FILE MUST BE SAVED AS "UTF-8 WITH BOM" FOR IT TO WORK
fixStringFromComSpec(str){
    charFix := {}
    charFix["\303\240"] := "à"
    charFix["\303\241"] := "á"
    charFix["\303\242"] := "â"
    charFix["\303\243"] := "ã"

    charFix["\303\200"] := "À"
    charFix["\303\201"] := "Á"
    charFix["\303\202"] := "Â"
    charFix["\303\203"] := "Ã"

    charFix["\303\247"] := "ç"
    charFix["\303\207"] := "Ç"

    charFix["\303\250"] := "è"
    charFix["\303\251"] := "é"
    charFix["\303\252"] := "ê"

    charFix["\303\210"] := "È"
    charFix["\303\211"] := "É"
    charFix["\303\212"] := "Ê"

    charFix["\303\262"] := "ò"
    charFix["\303\263"] := "ó"
    charFix["\303\264"] := "ô"
    charFix["\303\265"] := "õ"

    charFix["\303\222"] := "Ò"
    charFix["\303\223"] := "Ó"
    charFix["\303\224"] := "Ô"
    charFix["\303\225"] := "Õ"
    For k, v in charFix
    {
        str := StrReplace(str, k, v)
    }
    return str
}
Of course fixStringFromComSpec() can be expanded with more characters, etc :)

Post Reply

Return to “Ask for Help (v1)”