If Var is upper exhibiting weird behaviour

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Helios210
Posts: 2
Joined: 21 Jun 2018, 08:37

If Var is upper exhibiting weird behaviour

21 Jun 2018, 08:50

Hi all,

So I've been typing away at this problem for the better part of a day now and it's driving me nuts.

What I'm trying to do is fairly simple, I want to highlight text on the screen, run a function and if the text has capitals in it, replace it with a lowercase version, otherwise replace it with a sentence case version. Once I get this working I'll then make adjustments to capitalize each word.

The process I have so far goes as follows:

1) Send highlighted text to clipboard
2) Retrieve clipboard contents and store in variable
3) Use parsing loop to store each word in an array index
4) Use StrSplit to store each letter in an array index
5) Check if the letter is upper or lower case, if upper, set a flag to 1 ***
6) Modify the stored sentence according to the flag setting
7) Output the modified sentence

The problem I'm having is with Step 6, the offending code is:

Code: Select all

CheckCase(inArr) {
	result:=0
	Loop % inArr.length() {
		tmpVar2:=inArr[A_Index]
		
		if (%tmpVar2% is upper) 
		{
			result:=1
		}

		if (result == 1) 
		{
			return result
		}
	}
	return result
}
Should be simple right? This looks weird because I've been trying various sorts of combinations in a vain attempt to resolve the problem, I pass the sentence "this is a test" to this function as four arrays, one at a time [t,h,i,s] [i,s] and so on. Sometimes it detects "t" as uppercase, other times it detects "i" as uppercase. If I do the following:

Code: Select all

		if (t is upper) 
		{
			result:=1
		}

		if (tmpVar2 is upper) 
		{
			result:=1
		}

		if (tmpVar2 is upper) 
		{
			result:=1
		}

		if (%tmpVar2% is upper) 
		{
			result:=1
		}
Then debug with SciTE4 the first loop if is skipped, the middle two are both executed and the last one is skipped - to me this makes absolutely no damned sense!

My full code is below, can someone point out where I'm going wrong and save what's left of my sanity? Thanks!

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.

;AutoSentenceCase - This script takes selected text into the clipboard and converts between lower and sentence case.
;If any of the words are capatalised they will all be made lower case, if all of the words are already lower case sentence case will be applied.

Sleep, 300
Send ^c
Sleep, 100

inpArr:=[]
inpStr:=Clip()
i:=1

;Splits the string into its constituent words
Loop, parse, inpStr, " ",
{
	inpArr[i]:=A_LoopField
	i++
}

Loop % inpArr.length() {
	tmpArr:=StrSplit(inpArr[A_Index])

	result:=CheckCase(tmpArr)

	If (result=1)
	{
		outStr:=ChangeCase(inpStr,"L")
		break
	}
	else 
	{
		outStr:=ChangeCase(inpStr,"S")	
	}
}

SendRaw, %outStr% 

ExitApp

Clip(Text="", Reselect="") ; http://www.autohotkey.com/forum/viewtopic.php?p=467710 , modified February 19, 2013
{
	Static BackUpClip, Stored, LastClip
	If (A_ThisLabel = A_ThisFunc) {
		If (Clipboard == LastClip)
			Clipboard := BackUpClip
		BackUpClip := LastClip := Stored := ""
	} Else {
		If !Stored {
			Stored := True
			BackUpClip := ClipboardAll ; ClipboardAll must be on its own line
		} Else
			SetTimer, %A_ThisFunc%, Off
		LongCopy := A_TickCount, Clipboard := "", LongCopy -= A_TickCount ; LongCopy gauges the amount of time it takes to empty the clipboard which can predict how long the subsequent clipwait will need
		If (Text = "") {
			SendInput, ^c
			ClipWait, LongCopy ? 0.6 : 0.2, True
		} Else {
			Clipboard := LastClip := Text
			ClipWait, 10
			SendInput, ^v
		}
		SetTimer, %A_ThisFunc%, -700
		Sleep 20 ; Short sleep in case Clip() is followed by more keystrokes such as {Enter}
		If (Text = "")
			Return LastClip := Clipboard
		Else If (ReSelect = True) or (Reselect and (StrLen(Text) < 3000)) {
			StringReplace, Text, Text, `r, , All
			SendInput, % "{Shift Down}{Left " StrLen(Text) "}{Shift Up}"
		}
	}
	Return
	Clip:
	Return Clip()
}

ChangeCase(String,Type) { ;type is S,I,U,L, or T
If (Type="S") { ;Sentence case.
	X = I,AHK,AutoHotkey ;comma seperated list of words that should always be capitalized
	S := RegExReplace(RegExReplace(String, "(.*)", "$L{1}"), "(?<=[\.\!\?]\s|\n).|^.", "$U{0}")
	Loop Parse, X, `, ;Parse the exceptions
	S := RegExReplace(S,"i)\b" A_LoopField "\b", A_LoopField)
	Return S
}
If (Type="I") ;iNVERSE
	Return % RegExReplace(String, "([A-Z])|([a-z])", "$L1$U2")
Return % RegExReplace(String, "(.*)", "$" Type "{1}") ;All other types
}

CheckCase(inArr) {
	result:=0
	Loop % inArr.length() {
		tmpVar2:=inArr[A_Index]
		
		if (%tmpVar2% is upper) 
		{
			result:=1
		}

		if (result == 1) 
		{
			return result
		}
	}
	return result
}
User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: If Var is upper exhibiting weird behaviour

21 Jun 2018, 11:02

I didn't look at the rest of your script, but correct syntax for the if upper test is this:

If tmpVar2 is upper

Regards, Joe
User avatar
TheDewd
Posts: 1510
Joined: 19 Dec 2013, 11:16
Location: USA

Re: If Var is upper exhibiting weird behaviour

21 Jun 2018, 11:18

Am I correctly understanding the purpose of your script?

Code: Select all

#SingleInstance, Force

MyText := "this is A tEst"

MsgBox, % MyFunction(MyText)

MyFunction(String) {
	If (RegExMatch(String, "([A-Z])")) { ; If text contains capital letter --> convert all to lowercase and apply sentence-case formatting
		StringLower, String, String 
		return RegExReplace(String, "((^|[.!?]\s+)[a-z])", "$u1")
	} Else {
		return String ; Else text is already lowercase, so return same string without reformatting
	}
}
Helios210
Posts: 2
Joined: 21 Jun 2018, 08:37

Re: If Var is upper exhibiting weird behaviour

29 Jun 2018, 09:42

@JowWinograd - thanks, I did try that syntax to no avail :/

@TheDewd: Awesome! I'm pretty new to AHK so I'm not surprised that there was a super simple way to do this. It still really bugs me that if upper exhibited such random behavior, in the end I used the "ord" function to determine whether a letter was uppercase or not, my full code is below for anyone interested but I will definitely integrate your far simpler loop soon - thanks.

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.

;AutoSentenceCase - This script takes selected text into the clipboard and converts between lower and sentence case.
;If any of the words are capatalised they will all be made lower case, if all of the words are already lower case title case will be applied.

Sleep, 300
Send ^c
Sleep, 100

inpArr:=[]
inpStr:=Clip()
i:=1

;Splits the string into its constituent words
Loop, parse, inpStr, " ",
{
	inpArr[i]:=A_LoopField
	i++
}

Loop % inpArr.length() {
	tmpArr:=StrSplit(inpArr[A_Index])

	result:=CheckCase(tmpArr)

	If (result=1)
	{
		outStr:=ChangeCase(inpStr,"L")
		break
	}
	else 
	{
		outStr:=ChangeCase(inpStr,"T")	
	}
}

clipboard:=outStr

Send ^v

ExitApp

Clip(Text="", Reselect="") ; http://www.autohotkey.com/forum/viewtopic.php?p=467710 , modified February 19, 2013
{
	Static BackUpClip, Stored, LastClip
	If (A_ThisLabel = A_ThisFunc) {
		If (Clipboard == LastClip)
			Clipboard := BackUpClip
		BackUpClip := LastClip := Stored := ""
	} Else {
		If !Stored {
			Stored := True
			BackUpClip := ClipboardAll ; ClipboardAll must be on its own line
		} Else
			SetTimer, %A_ThisFunc%, Off
		LongCopy := A_TickCount, Clipboard := "", LongCopy -= A_TickCount ; LongCopy gauges the amount of time it takes to empty the clipboard which can predict how long the subsequent clipwait will need
		If (Text = "") {
			SendInput, ^c
			ClipWait, LongCopy ? 0.6 : 0.2, True
		} Else {
			Clipboard := LastClip := Text
			ClipWait, 10
			SendInput, ^v
		}
		SetTimer, %A_ThisFunc%, -700
		Sleep 20 ; Short sleep in case Clip() is followed by more keystrokes such as {Enter}
		If (Text = "")
			Return LastClip := Clipboard
		Else If (ReSelect = True) or (Reselect and (StrLen(Text) < 3000)) {
			StringReplace, Text, Text, `r, , All
			SendInput, % "{Shift Down}{Left " StrLen(Text) "}{Shift Up}"
		}
	}
	Return
	Clip:
	Return Clip()
}

ChangeCase(String,Type) { ;type is S,I,U,L, or T
If (Type="S") { ;Sentence case.
	X = I,AHK,AutoHotkey ;comma seperated list of words that should always be capitalized
	S := RegExReplace(RegExReplace(String, "(.*)", "$L{1}"), "(?<=[\.\!\?]\s|\n).|^.", "$U{0}")
	Loop Parse, X, `, ;Parse the exceptions
	S := RegExReplace(S,"i)\b" A_LoopField "\b", A_LoopField)
	Return S
}
If (Type="I") ;iNVERSE
	Return % RegExReplace(String, "([A-Z])|([a-z])", "$L1$U2")

If (Type="T") {
	newArr:=StrSplit(String," ")
	Loop % newArr.length() {
		tmpVar:=newArr[A_Index]
		If StrLen(tmpVar) == 1 {
			StringLower,tmpVar,tmpVar
			newArr[A_Index]:=tmpVar
		}
		Else {
			StringUpper,tmpVar,tmpVar,T
			newArr[A_Index]:=tmpVar
		}
	
	if (A_Index == 1) {
		out:=newArr[A_Index]
	}
	else {
		out.=" "
		out.=newArr[A_Index]
	}
}
	return out
}

return % RegExReplace(String, "(.*)", "$" Type "{1}") ;All other types
}

CheckCase(inArr) {
	result:=0
	Loop % inArr.length() {
		
		if (Ord(inArr[A_Index]) < 91)
		{
			result:=1
			return result
		}

	}
	return result
}
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: If Var is upper exhibiting weird behaviour

07 Jul 2018, 20:09

Helios210 wrote:It still really bugs me that if upper exhibited such random behavior,
It did not. What you were using was if (expression) with implicit concatenation of undefined variables (is and upper), not if var is type. As Joe noted, the correct syntax for if var is type is If tmpVar2 is upper, without parentheses or percent signs.
Note: The operators "between", "is", "in", and "contains" are not supported in expressions.
Source: If var is [not] type

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot] and 302 guests