text/list/table functions

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

text/list/table functions

18 Jan 2017, 02:19

I've made working attempts at, but am looking for the best ways to achieve:
- list comparison: items unique to list A / items unique to list B / items present in both [EDIT: see post lower down]
- table lookup: multiple values against a table/ini file [EDIT: just use an AHK array]
- table lookup: one value against a list (e.g. a spell list, do you use 26^2=676 variables to speed it up?) [EDIT: just use an AHK array][Note: for creating AHK arrays, it is faster to add keys in alphabetical order.]
- list remove duplicates: remove duplicates, maintain order [EDIT: see post lower down]
- list sort: sort list A based on list B, items in both should be in list B's order, the remaining items in list A should be in their original order [EDIT: see post lower down (list comparison)]
- list sort: start with paths/registry keys in their correct order, randomise, and restore original order [EDIT: will post code soon]
- text split: get start/end positions of nth line (see below) [EDIT: see post lower down]
- list line frequency: get frequency for each item, maintain order [EDIT: see post lower down]
- (each function would need case sensitive/case insensitive as an option)

get line: I made an attempt at this function below:
get nth/nth-to-last line of between a and b characters in length
(returning positions c and d, where the line starts after char c and ends before char d)
(note: the line could be blank, you can't use: starts with char c and ends with char d)

I'm thinking of methods including: multiple variables, arrays(?),
RegEx(?), add column - sort - remove column - sort back.
I've actually written all of these functions but they're untidy,
and am curious about any better methods, before I consider sharing.
These functions are the worst-looking/hardest-to-understand functions in my libraries.
(Something that became clear as I split my lib file into smaller files.)
I had hoped that maybe arrays might be a gamechanger, or some other method,
and wondered if anybody had any good ideas for these.

I was partly prompted by this recent question on csvs, that needs
the last non-blank line in a text file, of course you can use a parsing loop,
but what about more efficient ways:
(plus Excel can always corrupt/do weird things to the data,
because of assumptions it makes that can't be turned off)
Overwrite last row from one workbook to another - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=26949

[improved version of this in a post below]

Code: Select all

;==================================================

;this function is in beta stage
;if vNum is negative, the nth-to-last line positions are retrieved
;vRange1 and vRange2 allow you get the nth line with minimum/maximum length
;assumes CRLF line breaks
JEE_StrGetLinePos(ByRef vText, vNum, ByRef vPos1, ByRef vPos2, vRange1=0, vRange2="")
{
if (SubStr(vNum, 1, 1) = "-")
	vIsNeg := 1, vNum := SubStr(vNum, 2)
if vNum is not digit
	Return ""
if (vNum = "") OR (vNum = 0)
	Return ""
if vIsNeg
	vNum := -vNum

vCount := 0
vLen := StrLen(vText)

;==============================

;GET NTH LINE OF ANY LENGTH
if (vNum > 0) AND (vRange1=0) AND (vRange2="")
{
	vPos2 := InStr(vText "`r`n", "`n", 0, 1, vNum)
	if !vPos2
		Return 0, vPos1 := 0, vPos2 := 0
	vPos1 := InStr(vText "`r`n", "`n", 0, vPos2-vLen-3)
	Return 1, vPos1, vPos2 := vPos2-2
}

;==============================

;GET NTH LINE OF SPECIFIED LENGTH
if (vNum > 0)
{
	vPos2 := 0
	Loop
	{
		vPos1 := vPos2+1
		vPos2 := InStr(vText "`r`n", "`n", 0, vPos1+1)
		if !vPos2
			Return 0, vPos1 := 0, vPos2 := 0

		vDiff := vPos2-vPos1-1
		if (vDiff >= vRange1) AND ((vRange2 = "") OR (vDiff <= vRange2))
			vCount++
		if (vCount = vNum)
			Return 1, vPos1 := vPos1-1, vPos2 := vPos2-2
	}
}

;==============================

;GET NTH-TO-LAST LINE OF ANY LENGTH
if (vNum < 0) AND (vRange1=0) AND (vRange2="")
{
	vPos1 := InStr("`r`n" vText, "`n", 0, 0, -vNum)
	if !vPos1
		Return 0, vPos1 := 0, vPos2 := 0
	vPos2 := InStr("`r`n" vText "`r`n", "`n", 0, vPos1+1)
	Return 1, vPos1 := vPos1-2, vPos2 := vPos2-4
}

;==============================

;GET NTH-TO-LAST LINE OF SPECIFIED LENGTH
if (vNum < 0)
{
	vPos1 := vLen+4
	Loop
	{
		vPos2 := vPos1-1
		vPos1 := InStr("`r`n" vText "`r`n", "`n", 0, vPos2-vLen-4)
		if !vPos1
			Return 0, vPos1 := 0, vPos2 := 0

		vDiff := vPos2-vPos1
		if (vDiff >= vRange1) AND ((vRange2 = "") OR (vDiff <= vRange2))
			vCount++
		if (vCount = -vNum)
			Return 1, vPos1 := vPos1-2, vPos2 := vPos2-3
	}
}

;==============================

Return
}

;==================================================
Last edited by jeeswg on 06 Jun 2017, 18:01, edited 15 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
ryunp
Posts: 6
Joined: 14 Jan 2014, 02:01

Re: text/list/table functions

18 Jan 2017, 02:40

This massive text wall is hard to decipher. Are you looking for resources to learn the underlying data structures to accomplish these tasks? Or just looking for stack-overflow style homework answers?

The amount of specific issues is overwhelming. Can you identify just a few issues and elaborate on what you are trying to accomplish, and what's stopping you?
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: text/list/table functions

18 Jan 2017, 02:44

To be clear, I don't need anyone to write any code for me. I have functions that achieve these tasks already. I was more interested in general ideas, and what the current state of the art is. Possibly to provide some links, if there are good scripts, or point to any text function libraries. Basically I wasn't sure how to address this general problem of text functions, it doesn't seem to appear much on the forum. I thought I would at least try this approach.

In simple terms someone could go, OK for that one use arrays, for that one use RegEx etc.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
ryunp
Posts: 6
Joined: 14 Jan 2014, 02:01

Re: text/list/table functions

18 Jan 2017, 03:07

I've always enjoyed JavaScript's architecture; try looking through MDN's docs on the String object. You will see a list of methods on the left sidebar. These are all the functions provided for string operations.

I also suggest looking at Array object to see how they deal with lists of elements. Their functional approach is noteworthy and incredibly powerful.

Best way to learn is study what's already been done. I've actually been rewriting most of the Array methods from JavaScript's Array object for AHK. For instance, Array.filter():

Code: Select all

array := [1,2,3,4,5,6]
array2 := array_filter(array, func("isEvenFilter"))

msgbox % "new array count: " array2.Length()

isEvenFilter(element, index, array) {

	return (mod(element, 2) = 0)
}

array_filter(array, callback) {
	
	new_array := []

	for index, element in array
		if (callback.Call(element, index, array))
			new_array.push(element)

	return new_array
}
If this material is overwhelming, there is other sources I can point you to.
Last edited by ryunp on 18 Jan 2017, 03:41, edited 1 time in total.
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: text/list/table functions

18 Jan 2017, 03:24

Thanks for your response, I will investigate this further.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
ryunp
Posts: 6
Joined: 14 Jan 2014, 02:01

Re: text/list/table functions

18 Jan 2017, 03:40

If you end up needing JavaScript-esk Array functions, I've ported over most of them: https://github.com/ryunp/ahk-array
Last edited by ryunp on 19 Jan 2017, 05:10, edited 1 time in total.
FanaticGuru
Posts: 1380
Joined: 30 Sep 2013, 22:25

Re: text/list/table functions

18 Jan 2017, 19:59

If you are looking for some functions for strings and arrays, I have found String Things useful.
https://autohotkey.com/boards/viewtopic.php?f=6&t=53

I especially like ST_printarr when debugging a script to get a visual of an arrays contents. Its recursive technique of walking through all the elements of a multi-dimensional array has been useful for me in several scripts.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
User avatar
tidbit
Posts: 1154
Joined: 29 Sep 2013, 17:15
Location: USA

Re: text/list/table functions

18 Jan 2017, 20:34

didn't read all the replies but:
lots of text this/functions:
1) https://autohotkey.com/boards/viewtopic.php?t=14515
2) https://autohotkey.com/boards/viewtopic.php?f=6&t=53
rawr. fear me.
*poke*
Is it December 21, 2012 yet?
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: text/list/table functions

19 Jan 2017, 02:03

Wow ahk7, the Table lib has the kind of bold ambition I'm looking for,
thanks very much.
It looks so far that I should try and publish the functions I mentioned,
once checked over, many seem to be missing from other libraries.
I'm not especially interested in list functions per se,
but when you need them, you need them, and I've tried to write them,
and they can't just work, they have to be fast, and not have any bugs!
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: text/list/table functions

19 Jan 2017, 02:06

Thanks very much FanaticGuru and tidbit, I will investigate further.

Btw tidbit your avatar is the most awesome, ... and that shade of green!
I wish there were more avatars on the new forum,
like there were on the old one.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
tidbit
Posts: 1154
Joined: 29 Sep 2013, 17:15
Location: USA

Re: text/list/table functions

19 Jan 2017, 11:23

Thanks, made it myself :)
I like owls (though, not my fav animal/bird), I also like the color teal (technically "Caribbean green" or "Sea Green 3"). the pink is because that was the color of admins/mods names on the old-old-old forum.
rawr. fear me.
*poke*
Is it December 21, 2012 yet?
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: text/list/table functions

19 Jan 2017, 11:48

Great story about the owl. They are wise, as they can see in the dark.
I keep a lucky Greek one euro coin with an owl on it.
Owls also remind me of Rupert and the Frog Song LOL.

I really need to become a *sort of* graphic designer, it's my one shortcoming,
I think I would love it. Yeah, maybe I need a graphics tablet and to get back to drawing AFK as well.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
tidbit
Posts: 1154
Joined: 29 Sep 2013, 17:15
Location: USA

Re: text/list/table functions

19 Jan 2017, 11:54

this is offtopic but it's your topic and you started it :D

I made this, and most of my stuff, in inkscape (svg > bitmap). Using a mouse (never owned, but always wanted, a drawing tablet). I'd get Illustrator or CorelDraw, but they are $500+. and the newest Illustrator (as with all adobe things) are locked behind the crappy subscription cloud now. I don't pirate stuff :/
rawr. fear me.
*poke*
Is it December 21, 2012 yet?
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: text/list/table functions

27 Feb 2017, 18:20

I have an improved version of a function to get the position of the nth/nth-to-last of any/a specified length. I also have a simpler slower version, useful for checking that the faster function works and in case there are any bugs in the faster function. Please make any comments or notify of any errors, it is very hard to guarantee correctness.

Code: Select all

;==================================================

;if vNum is negative, the nth-to-last line positions are retrieved
;vRange1 and vRange2 allow you get the nth line with minimum/maximum length
;assumes CRLF line breaks
;e.g. 'aaabbbccc', for aaa the caret positions before/after it are (0,3)
;e.g. 'aaabbbccc', for bbb the caret positions before/after it are (3,6)
JEE_StrGetLinePos(ByRef vText, vNum, ByRef vPos1, ByRef vPos2, vRange1=0, vRange2="")
{
	vPos1 := vPos2 := 0
	if !RegExMatch(vNum, "^(-|)\d+$") || (vNum = 0)
		return 0
	vLen := StrLen(vText)
	vIsAhkV1 := !!SubStr(1,0)

	;get nth/nth-to-last line of any length
	if (vRange1=0) && (vRange2="")
	{
		if (vNum = 1)
		{
			vPos1 := 1, vPos2 := InStr(vText, "`n")-2
			if (vPos2 = -2)
				vPos2 := vLen
			vPos1-- ;it should be one below the matching char
			return 1
		}
		if (vNum > 1)
		{
			if !(vPos1 := InStr(vText, "`n", 0, 1, vNum-1))
				return 0
			vPos1 := vPos1+1, vPos2 := InStr(vText, "`n", 0, vPos1)-2
			if (vPos2 = -2)
				vPos2 := vLen
			vPos1-- ;it should be one below the matching char
			return 1
		}
		if (vNum = -1)
		{
			vPos2 := vLen, vPos1 := InStr(vText, "`n", 0, vIsAhkV1-1)+1
			vPos1-- ;it should be one below the matching char
			return 1
		}
		if (vNum < 0)
		{
			if !(vPos2 := InStr(vText, "`n", 0, vIsAhkV1-1, -vNum-1))
				return 0
			vPos2 -= 2, vPos1 := InStr(vText, "`n", 0, vIsAhkV1-vLen+vPos2-1)+1
			{
				vPos1-- ;it should be one below the matching char
				return 1
			}
		}
	}

	;==============================

	;get nth line of specified length
	if (vNum > 0)
	{
		vCount := 0, vPos1 := 1
		Loop
		{
			vPos2 := InStr(vText, "`n", 0, vPos1)-2
			if (vPos2 = -2)
				vPos2 := vLen, vDoEnd := 1
			vDiff := vPos2-vPos1+1
			if (vDiff >= vRange1) && ((vRange2 = "") || (vDiff <= vRange2))
				vCount++
			if (vCount = vNum)
			{
				vPos1-- ;it should be one below the matching char
				return 1
			}
			if vDoEnd
			{
				vPos1 := vPos2 := 0
				return 0
			}
			vPos1 := vPos2+3
		}
	}

	;==============================

	;get nth-to-last line of specified length
	if (vNum < 0)
	{
		vCount := 0, vPos2 := vLen
		Loop
		{
			vPos1 := InStr(vText, "`n", 0, vIsAhkV1-vLen+vPos2-1)+1
			if (vPos1 = 1)
				vDoEnd := 1
			vDiff := vPos2-vPos1+1
			if (vDiff >= vRange1) && ((vRange2 = "") || (vDiff <= vRange2))
				vCount++
			if (vCount = -vNum)
			{
				vPos1-- ;it should be one below the matching char
				return 1
			}
			if vDoEnd
			{
				vPos1 := vPos2 := 0
				return 0
			}
			vPos2 := vPos1-3
		}
	}

	;==============================

	return 0
}

;==================================================

;simpler slower(?) version of the same function
JEE_StrGetLinePos2(vText, vNum, ByRef vPos1, ByRef vPos2, vRange1=0, vRange2="")
{
	if (vNum = 0)
	{
		vPos1 := vPos2 := 0
		return
	}

	vText := StrReplace(vText, "`r`n", "`n")
	oArray := StrSplit(vText, "`n")
	vMax := oArray.MaxIndex()

	vDiff := (vNum>0) ? 1 : -1
	vIndex := (vNum>0) ? 1 : vMax
	vCount := 0
	vNum2 := Abs(vNum)
	vRet := 0

	Loop, % vMax
	{
		vTemp := oArray[vIndex]
		vLen := StrLen(vTemp)
		if (vLen >= vRange1) && ((vRange2 = "") || (vLen <= vRange2))
			vCount++
		if (vCount = vNum2)
		{
			vRet := 1
			break
		}
		vIndex += vDiff
	}

	vChars := 0
	vPos1 := vPos2 := 0
	Loop, % vMax
	{
		vTemp := oArray[A_Index]
		vChars1 := vChars
		vLen := StrLen(vTemp)
		vChars += vLen
		vChars2 := vChars
		if (A_Index = vIndex)
		{
			vPos1 := vChars1, vPos2 := vChars2
			break
		}
		vChars += 2
	}

	return vRet
}

;==================================================
Last edited by jeeswg on 23 May 2017, 08:51, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: text/list/table functions

27 Feb 2017, 19:36

Has anyone written a function to add indentation to lines of code?

Someone did link me to this, but I believe it's written in php not AHK:
online converter: converts your autohotkey code into pretty indented source code. - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?t=8678
Autohotkey-code-prettify - in a web page - Github Project Hosting
http://sl5.it/SL5_preg_contentFinder/ex ... e_code.php

Anyhow, I have written a function to add indentation to lines of code, I can't guarantee that it will work in all circumstances, however, it has worked correctly on all of my code that I tested it on.

[EDIT: 2017-03-22][This is pretty good, but it's getting the indentation wrong occasionally, in a few circumstances. I have mostly finished a more robust version.][More difficult is handling custom function names, or blocks without a preceding function name, which AHK allows, I'm working on solutions.][Basically my tests will be complete, when I can correctly indent an entire AHK script.]

Code: Select all

JEE_StrIndentCode(vText)
{
vOutput := ""
VarSetCapacity(vOutput, StrLen(vText)*2)
vText := StrReplace(vText, "`r`n", "`n")
vCount := 0 ;number of tabs to prepend to line
vAdjNow := 0 ;'adjust now': alter number of tabs for this line
vAdjMode := 0 ;'adjust mode': alter number of tabs for future lines
;vList := "if ,else,Loop,IfWin,for "
vList := "Catch,Else,Finally,For ,If,Loop,Try,While"
vList := StrReplace(vList, ",", "|")

Loop, Parse, vText, `n
{
	vAdjNow := vAdjMode
	vTemp := LTrim(A_LoopField)

	if (vTemp = "")
	{
		vOutput .= "`r`n"
		continue
	}

	vType := 0
	if !vType && (SubStr(vTemp, 1, 1) = "{")
		vType := 2
	if !vType && (SubStr(vTemp, 1, 1) = "}")
		vType := 3
	;if !vType && JEE_StrStarts(vTemp, vList, "|")
	if !vType && RegExMatch(vTemp, "i)^(" vList ")")
		vType := 1

	;CRITERIA - line is 'if/else...'
	if (vType = 1)
		vCount := vCount+1, vAdjNow := -1, vAdjMode := 1

	;CRITERIA - line is '{'
	if (vType = 2)
		vAdjNow := -1
	if (vType = 2) && vAdjMode
		vAdjMode := 0

	;CRITERIA - line is '}'
	if (vType = 3)
		vCount := vCount-1

	;CRITERIA - line is not '{' or '}' or 'if/else...'
	if (vType = 0) && vAdjMode
		vCount := vCount-1, vAdjMode := 0, vAdjNow := 1

	;vOutput .= JEE_StrRept("`t", vCount+vAdjNow) vTemp "`r`n"
	Loop, % vCount+vAdjNow
		vOutput .= "`t"
	vOutput .= vTemp "`r`n"
}

vOutput := SubStr(vOutput, 1, -2)
Return vOutput
}
If anyone has doubts about the value of indentation, please post below, because, apart from in a few situations, I don't think it adds much value either, it's more a tradition. It looks 'pretty' and it looks 'professional'.

Some further links I found:
Syntax-Tidy for scripts (indentation and case correction) - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/2385 ... orrection/
Auto-Syntax-Tidy = Somebody has it ? - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?t=7317
Line based Parser for AHK Code v1.2 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 850#p43850

[EDIT:]
This is designed for working on a block of code/a subroutine, not on a whole script. Plus, use something like WinMerge to check before and after. Btw also, continuation sections, could potentially be an issue, if they contain lines that start with certain strings.

[EDIT: 2017-09-26]
New function: There are certain coding styles it doesn't (yet?) support, however, I was able to correctly indent my main written-by-me 40 or so .ahk files (i.e. scripts and function libraries).
indent code (automated code indentation) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=37270
Last edited by jeeswg on 25 Sep 2017, 19:21, edited 3 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
FanaticGuru
Posts: 1380
Joined: 30 Sep 2013, 22:25

Re: text/list/table functions

27 Feb 2017, 21:18

There is a reason professional programmers' work looks professional, it allows them to do their job more professionally. Professional looking code is easier to understand for both the professional that wrote it and other professionals that need to understand it. A uniform formatting style is pretty much required to work as part of a professional programming team. Everyone on the team is expected to use a very similar formatting style and also coding style.

If you want the masses to accept and use your code, you are going to have to bite-the-bullet and conform to the masses, which you seem to be trying.

I hate spending the time to comment code as I find that the boring part of coding but I do try to put some extra effort in to commenting code I post. I am posting it to help people and comments are very helpful for others to understand code.

As far as I know there is no really good formatting scripts for AHK. There was Tidy Code by toralf but it is out of date to the point of not useable. I am talking code that can properly format pretty much any script. Handling functions, subroutines, hotkeys, hotstrings, comments, quotes, escaped quotes, join, etc. etc. You think you have it then run another large library or script from the forum through it and find another exception to the rule.

Because of several scripts I have written I am pretty well verse on the ins-and-outs of parsing the text of AHK files and have studied toralf's code extensively especially the RegEx. I have thought about writing a AHK formatter but once you get into it, it is quite a bit of work to handle all the formatting that AHK will accept. I might look at working on it again but the custom setup I have for SciTE4AutoHotkey now helps a lot with keeping my formatting consistent as I write it. My plan at one time was to be able to choose different formatting styles. https://en.wikipedia.org/wiki/Indent_style

Oh by the way, in almost every accepted style there should be an indent after a function definition:

Code: Select all

JEE_StrIndentCode(vText)
{
	vOutput := ""
FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: text/list/table functions (latest: add indentation, get nth(-to-last) line of specified length, html <> text)

04 Mar 2017, 20:30

Convert html to text / text to html via an HTMLFile object. Deal with character entities.

Code: Select all

q:: ;examples: html to text / text to html
;TEST 1 - html to text
vHtml := "a & b"
MsgBox % JEE_StrHtmlToText(vHtml)

;TEST 2 - text to html
vText := "c & d"
MsgBox % JEE_StrTextToHtml(vText)

;TEST 3 - text (255 chars) to html to text
;(final text should be the same as original text but isn't)(issues with 6 chars: 9,10,11,12,13,160)
vText := ""
Loop, 255
	vText .= Chr(A_Index)
vHtml := JEE_StrTextToHtml(vText)
MsgBox % (vText = JEE_StrHtmlToText(vHtml))
;Clipboard := vText "`r`n`r`n" JEE_StrHtmlToText(vHtml)

;TEST 4 - text (255 chars, 6 chars removed) to html to text
;(final text is the same as original text)
Loop, 255
	vText .= Chr(A_Index)
vList := "9,10,11,12,13,160"
Loop, Parse, vList, `,
	vText := StrReplace(vText, Chr(A_LoopField), "")
vHtml := JEE_StrTextToHtml(vText)
MsgBox % (vText = JEE_StrHtmlToText(vHtml))
;Clipboard := vText "`r`n`r`n" JEE_StrHtmlToText(vHtml)
Return

JEE_StrHtmlToText(vHtml)
{
oHTML := ComObjCreate("HTMLFile")
oHTML.write("<title>" vHtml "</title>")
vText := oHTML.getElementsByTagName("title")[0].innerText
oHTML := ""
Return vText
}

JEE_StrTextToHtml(vText)
{
oHTML := ComObjCreate("HTMLFile")
oHTML.write("<title></title>")
oHTML.getElementsByTagName("title")[0].value := vText
vHtml := oHTML.getElementsByTagName("title")[0].outerHTML
oHTML := ""
Return SubStr(vHtml, 15, -10)
}
I would be interested in any definitive lists/methods for character entities.

Links:
[The Transform command can do text to html, but this will be removed in AHK v2]
Transform
https://autohotkey.com/docs/commands/Transform.htm
HTML, String [, Flags]

convert html special characters - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/9203 ... haracters/
UTF-8 HEX Text Conversion - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/9324 ... onversion/
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: text/list/table functions (latest: add indentation, get nth(-to-last) line of specified length, html to/from text)

30 May 2017, 19:42

Note: these functions have been tested but not exhaustively.

I may introduce versions of these functions that use one of 4 custom classes: case sensitive/insensitive, alphabetical/date creation order. I.e. custom types of array similar to the standard AHK arrays and the Scripting.Dictionary object.

Basic tips regarding objects:
- AHK arrays are case insensitive and alphabetical order.
- The Scripting.Dictionary object is case sensitive and date creation (date added) order.
- AHK arrays can handle string and numeric keys, e.g. it can have a numeric '1' key, and a string '1' key. The Scripting.Dictionary cannot handle numeric keys.
- One way to maintain the order of keys, is for the main array, with key K, to have an auxiliary array, with key N (number) and value K. You can then loop through the auxiliary array to retrieve the keys in order.

to create 'key 1, value 1', where value 1 is the name of a key in another array.

Code: Select all

;1 list - frequency count
;1 list - remove duplicates
;2 lists - compare (unique to A/unique to B/present in both)

;list of functions:
;JEE_StrFreqCIA(ByRef vText)
;JEE_StrFreqCID(ByRef vText)
;JEE_StrFreqCID2(ByRef vText)
;JEE_StrFreqCSA(ByRef vText)
;JEE_StrFreqCSD(ByRef vText)
;JEE_StrRemoveDupsCIA(ByRef vText)
;JEE_StrRemoveDupsCID(ByRef vText)
;JEE_StrRemoveDupsCID2(ByRef vText)
;JEE_StrRemoveDupsCSA(ByRef vText)
;JEE_StrRemoveDupsCSD(ByRef vText)
;JEE_StrListCompareCIA(ByRef vText1, ByRef vText2, ByRef vOutputAB, ByRef vOutputA, ByRef vOutputB)
;JEE_StrListCompareCID(ByRef vText1, ByRef vText2, ByRef vOutputAB, ByRef vOutputA, ByRef vOutputB)
;JEE_StrListCompareCID2(ByRef vText1, ByRef vText2, ByRef vOutputAB, ByRef vOutputA, ByRef vOutputB)
;JEE_StrListCompareCSA(ByRef vText1, ByRef vText2, ByRef vOutputAB, ByRef vOutputA, ByRef vOutputB)
;JEE_StrListCompareCSD(ByRef vText1, ByRef vText2, ByRef vOutputAB, ByRef vOutputA, ByRef vOutputB)

;some functions require:
;JEE_SortCasIns

;==================================================

;ARRAY TYPE 1: 'CIA', case insensitive, alphabetical order
;ARRAY TYPE 2: 'CID', case insensitive, date creation order
;ARRAY TYPE 3: 'CSA', case sensitive, alphabetical order
;ARRAY TYPE 4: 'CSD', case sensitive, date creation order

;==================================================

;list line frequency ('CIA', case insensitive, alphabetical order)
JEE_StrFreqCIA(ByRef vText)
{
	oArray := {}
	StrReplace(vText, "`n", "", vCount)
	oArray.SetCapacity(vCount+1)
	Loop, Parse, vText, `n, `r
		if oArray.HasKey("" A_LoopField)
			oArray["" A_LoopField]++
		else
			oArray["" A_LoopField] := 1
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2*2)
	for vKey, vValue in oArray
		vOutput .= vValue "`t" vKey "`r`n"
	oArray := ""
	return vOutput
}

;==================================================

;list line frequency ('CID', case insensitive, date creation order)
JEE_StrFreqCID(ByRef vText)
{
	oArray := ComObjCreate("Scripting.Dictionary"), oArray2 := {}
	Loop, Parse, vText, `n, `r
		if oArray2.HasKey("" A_LoopField)
			oArray.item(oArray2["" A_LoopField])++
		else
			oArray.item("" A_LoopField) := 1, oArray2["" A_LoopField] := "" A_LoopField
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2*2)
	for vKey, vValue in oArray
		vOutput .= oArray.item(vKey) "`t" vKey "`r`n"
	oArray := oArray2 := ""
	return vOutput
}

;==================================================

;list line frequency ('CID', case insensitive, date creation order)
;slower alternative to JEE_StrFreqCID
JEE_StrFreqCID2(ByRef vText)
{
	oArray := {}, oArray2 := {}
	StrReplace(vText, "`n", "", vCount)
	oArray.SetCapacity(vCount+1)
	oArray2.SetCapacity(vCount+1)
	Loop, Parse, vText, `n, `r
		if oArray.HasKey("" A_LoopField)
			oArray["" A_LoopField]++
		else
			oArray["" A_LoopField] := 1, oArray2.Push("" A_LoopField)
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2*2)
	for _, vValue in oArray2
		vOutput .= oArray["" vValue] "`t" vValue "`r`n"
	oArray := oArray2 := ""
	return vOutput
}

;==================================================

;list line frequency ('CSA', case sensitive, alphabetical order)
JEE_StrFreqCSA(ByRef vText, vCSWithinCI=0)
{
	oArray := ComObjCreate("Scripting.Dictionary")
	vText2 := StrReplace(vText, "`r`n", "`n")
	Sort, vText2, CS
	;e.g. case sensitive: 'A,B,C,a,b,c'
	;e.g. 'CS within CI': 'A,a,B,b,C,c'
	if vCSWithinCI
		Sort, vText2, F JEE_SortCasIns
	Loop, Parse, vText2, `n, `r
		oArray.item("" A_LoopField) := 0
	Loop, Parse, vText, `n, `r
		oArray.item("" A_LoopField)++
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2*2)
	for vKey in oArray
		vOutput .= oArray.item(vKey) "`t" vKey "`r`n"
	oArray := ""
	return vOutput
}

;==================================================

;list line frequency ('CSD', case sensitive, date creation order)
JEE_StrFreqCSD(ByRef vText)
{
	oArray := ComObjCreate("Scripting.Dictionary")
	Loop, Parse, vText, `n, `r
		if !(oArray.item("" A_LoopField) = "")
			oArray.item("" A_LoopField)++
		else
			oArray.item("" A_LoopField) := 1
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2*2)
	for vKey in oArray
		vOutput .= oArray.item(vKey) "`t" vKey "`r`n"
	oArray := ""
	return vOutput
}

;==================================================

JEE_StrRemoveDupsCIA(ByRef vText)
{
	oArray := {}
	Loop, Parse, vText, `n, `r
		if !oArray.HasKey("" A_LoopField)
			oArray["" A_LoopField] := 1
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2+2)
	for vKey in oArray
		vOutput .= vKey "`n"
	oArray := ""
	return SubStr(vOutput, 1, -1)
}

;==================================================

;list line frequency ('CID', case insensitive, date creation order)
JEE_StrRemoveDupsCID(ByRef vText)
{
	oArray := ComObjCreate("Scripting.Dictionary"), oArray2 := {}
	Loop, Parse, vText, `n, `r
		if !oArray2.HasKey("" A_LoopField)
			oArray.item("" A_LoopField) := "", oArray2["" A_LoopField] := ""
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2*2)
	for vKey in oArray
		vOutput .= vKey "`n"
	oArray := oArray2 := ""
	return SubStr(vOutput, 1, -1)
}

;==================================================

;list line frequency ('CID', case insensitive, date creation order)
;roughly equal speed alternative to JEE_StrRemoveDupsCID based on JEE_StrFreqCID
JEE_StrRemoveDupsCID2(ByRef vText)
{
	oArray := {}, oArray2 := {}
	StrReplace(vText, "`n", "", vCount)
	oArray.SetCapacity(vCount+1)
	oArray2.SetCapacity(vCount+1)
	Loop, Parse, vText, `n, `r
		if !oArray.HasKey("" A_LoopField)
			oArray["" A_LoopField] := "", oArray2.Push("" A_LoopField)
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2+2)
	for _, vValue in oArray2
		vOutput .= vValue "`n"
	oArray := oArray2 := ""
	return SubStr(vOutput, 1, -1)
}

;==================================================

JEE_StrRemoveDupsCSA(ByRef vText, vCSWithinCI=0)
{
	vOutput := vText
	Sort, vOutput, U CS
	;e.g. case sensitive: 'A,B,C,a,b,c'
	;e.g. 'CS within CI': 'A,a,B,b,C,c'
	if vCSWithinCI
		Sort, vOutput, F JEE_SortCasIns
	return vOutput
}

;==================================================

;list line frequency ('CSD', case sensitive, date creation order)
JEE_StrRemoveDupsCSD(ByRef vText)
{
	oArray := ComObjCreate("Scripting.Dictionary")
	Loop, Parse, vText, `n, `r
		if !oArray.Exists("" A_LoopField)
			oArray.item("" A_LoopField) := ""
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2+2)
	for vKey in oArray
		vOutput .= vKey "`n"
	oArray := ""
	return SubStr(vOutput, 1, -1)
}

;==================================================

;17:17 11/05/2017
;stage 1, list A:
;for each item, add key with value 1

;stage 2, list B:
;if item exists and has value 1, set value to 0
;if item exists and has value 0, do nothing
;if item doesn't exist, add key with value - 1

;stage 3:
;1/0/-1 = unique to A/present in both (in the list A's order)/unique to B

;==================================================

;list line frequency ('CIA', case insensitive, alphabetical order)
JEE_StrListCompareCIA(ByRef vText1, ByRef vText2, ByRef vOutputAB, ByRef vOutputA, ByRef vOutputB)
{
	oArray := {}
	StrReplace(vText1, "`n", "", vCount1)
	StrReplace(vText2, "`n", "", vCount2)
	vMax := StrLen(vNum1) > StrLen(vNum2) ? StrLen(vNum1) : StrLen(vNum2)
	oArray.SetCapacity(vCount1+vCount2+2)
	Loop, Parse, vText1, `n, `r
		if !oArray.HasKey("" A_LoopField)
			oArray["" A_LoopField] := 1
	Loop, Parse, vText2, `n, `r
		if !oArray.HasKey("" A_LoopField)
			oArray["" A_LoopField] := -1
		else if (oArray["" A_LoopField] = 1)
			oArray["" A_LoopField] := 0
	VarSetCapacity(vOutputAB, vMax*2)
	VarSetCapacity(vOutputA, vMax*2)
	VarSetCapacity(vOutputB, vMax*2)
	for vKey, vValue in oArray
		if (vValue = 0)
			vOutputAB .= vKey "`r`n"
		else if (vValue = 1)
			vOutputA .= vKey "`r`n"
		else
			vOutputB .= vKey "`r`n"
	oArray := ""
}

;==================================================

;list line frequency ('CID', case insensitive, date creation order)
JEE_StrListCompareCID(ByRef vText1, ByRef vText2, ByRef vOutputAB, ByRef vOutputA, ByRef vOutputB)
{
	oArray := ComObjCreate("Scripting.Dictionary"), oArray2 := {}
	Loop, Parse, vText1, `n, `r
		if !oArray2.HasKey("" A_LoopField)
			oArray.item("" A_LoopField) := 1, oArray2["" A_LoopField] := "" A_LoopField
	Loop, Parse, vText2, `n, `r
		if !oArray2.HasKey("" A_LoopField)
			oArray.item("" A_LoopField) := -1, oArray2["" A_LoopField] := "" A_LoopField
		else if (oArray.item("" oArray2["" A_LoopField]) = 1)
			oArray.item("" A_LoopField) := 0
	VarSetCapacity(vOutputAB, vMax*2)
	VarSetCapacity(vOutputA, vMax*2)
	VarSetCapacity(vOutputB, vMax*2)
	for _, vValue in oArray2
		if ((vValue2 := oArray.item("" vValue)) = 0)
			vOutputAB .= vValue "`r`n"
		else if (vValue2 = 1)
			vOutputA .= vValue "`r`n"
		else
			vOutputB .= vValue "`r`n"
	oArray := oArray2 := ""
}

;==================================================

;list line frequency ('CID', case insensitive, date creation order)
;slower alternative to JEE_StrListCompareCID
JEE_StrListCompareCID2(ByRef vText1, ByRef vText2, ByRef vOutputAB, ByRef vOutputA, ByRef vOutputB)
{
	oArray := {}, oArray2 := {}
	StrReplace(vText1, "`n", "", vCount1)
	StrReplace(vText2, "`n", "", vCount2)
	oArray.SetCapacity(vCount1+vCount2+2)
	oArray2.SetCapacity(vCount1+vCount2+2)
	Loop, Parse, vText1, `n, `r
		if !oArray.HasKey("" A_LoopField)
			oArray["" A_LoopField] := 1, oArray2.Push("" A_LoopField)
	Loop, Parse, vText2, `n, `r
		if !oArray.HasKey("" A_LoopField)
			oArray["" A_LoopField] := -1, oArray2.Push("" A_LoopField)
		else if (oArray["" A_LoopField] = 1)
			oArray["" A_LoopField] := 0
	vOutput := ""
	VarSetCapacity(vOutputAB, vMax*2)
	VarSetCapacity(vOutputA, vMax*2)
	VarSetCapacity(vOutputB, vMax*2)
	for _, vValue in oArray2
		if ((vValue2 := oArray["" vValue]) = 0)
			vOutputAB .= vValue "`r`n"
		else if (vValue2 = 1)
			vOutputA .= vValue "`r`n"
		else
			vOutputB .= vValue "`r`n"
	oArray := oArray2 := ""
}

;==================================================

;list line frequency ('CSA', case sensitive, alphabetical order)
JEE_StrListCompareCSA(ByRef vText1, ByRef vText2, ByRef vOutputAB, ByRef vOutputA, ByRef vOutputB, vCSWithinCI=0)
{
	oArray := ComObjCreate("Scripting.Dictionary")
	vText1X := StrReplace(vText1, "`r`n", "`n")
	vText1X := StrReplace(vText2, "`r`n", "`n")
	Sort, vText1X, CS
	Sort, vText2X, CS
	;e.g. case sensitive: 'A,B,C,a,b,c'
	;e.g. 'CS within CI': 'A,a,B,b,C,c'
	if vCSWithinCI
	{
		Sort, vText1X, F JEE_SortCasIns
		Sort, vText2X, F JEE_SortCasIns
	}
	Loop, Parse, vText1X, `n, `r
		if !oArray.Exists("" A_LoopField)
			oArray.item("" A_LoopField) := 1
	Loop, Parse, vText2X, `n, `r
		if !oArray.Exists("" A_LoopField)
			oArray.item("" A_LoopField) := -1
		else if (oArray.item("" A_LoopField) = 1)
			oArray.item("" A_LoopField) := 0
	VarSetCapacity(vOutputAB, vMax*2)
	VarSetCapacity(vOutputA, vMax*2)
	VarSetCapacity(vOutputB, vMax*2)
	for vKey in oArray
		if ((vValue := oArray.item(vKey)) = 0)
			vOutputAB .= vKey "`r`n"
		else if (vValue = 1)
			vOutputA .= vKey "`r`n"
		else
			vOutputB .= vKey "`r`n"
	oArray := ""
}

;==================================================

;list line frequency ('CSD', case sensitive, date creation order)
JEE_StrListCompareCSD(ByRef vText1, ByRef vText2, ByRef vOutputAB, ByRef vOutputA, ByRef vOutputB)
{
	oArray := ComObjCreate("Scripting.Dictionary")
	Loop, Parse, vText1, `n, `r
		if !oArray.Exists("" A_LoopField)
			oArray.item("" A_LoopField) := 1
	Loop, Parse, vText2, `n, `r
		if !oArray.Exists("" A_LoopField)
			oArray.item("" A_LoopField) := -1
		else if (oArray.item("" A_LoopField) = 1)
			oArray.item("" A_LoopField) := 0
	VarSetCapacity(vOutputAB, vMax*2)
	VarSetCapacity(vOutputA, vMax*2)
	VarSetCapacity(vOutputB, vMax*2)
	for vKey in oArray
		if ((vValue := oArray.item(vKey)) = 0)
			vOutputAB .= vKey "`r`n"
		else if (vValue = 1)
			vOutputA .= vKey "`r`n"
		else
			vOutputB .= vKey "`r`n"
	oArray := ""
}

;==================================================

JEE_SortCasIns(vTextA, vTextB, vOffset) ;for use with AHK's Sort command
{
	vSCS := A_StringCaseSense
	StringCaseSense, Off
	vRet := ("" vTextA) > ("" vTextB) ? 1 : ("" vTextA) < ("" vTextB) ? -1 : -vOffset
	StringCaseSense, % vSCS
	return vRet
}

;==================================================
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: text/list/table functions (latest: add indentation, get nth(-to-last) line of specified length, html to/from text)

06 Jun 2017, 16:37

JEE_SortPathFindNextFile(vTextA, vTextB, vOffset) ;for use with AHK's Sort command
JEE_SortPathRegEdit(vTextA, vTextB, vOffset) ;for use with AHK's Sort command

Any comments are welcome.

Code: Select all

JEE_SortPathFindNextFile(vTextA, vTextB, vOffset) ;for use with AHK's Sort command
{
	StringUpper, vTextA, vTextA
	StringUpper, vTextB, vTextB
	if ("" vTextA = "" vTextB)
		return -vOffset

	oTempA := StrSplit(vTextA, "\")
	oTempB := StrSplit(vTextB, "\")
	vMin := oTempA.Length() < oTempB.Length() ? oTempA.Length() : oTempB.Length()

	Loop, % vMin
		if !(oTempA[A_Index] = oTempB[A_Index])
		{
			vTextA := oTempA[A_Index], vTextB := oTempB[A_Index], vIndex := A_Index
			break
		}

	if (vIndex = vMin) && !(oTempA.Length() = oTempB.Length())
		if (oTempA.Length() = vMin)
			return -1
		else if (oTempB.Length() = vMin)
			return 1

	vSCS := A_StringCaseSense
	StringCaseSense, On
	vRet := ("" vTextA) > ("" vTextB) ? 1 : ("" vTextA) < ("" vTextB) ? -1 : -vOffset
	StringCaseSense, % vSCS
	return vRet
}

;==================================================

JEE_SortPathRegEdit(vTextA, vTextB, vOffset) ;for use with AHK's Sort command
{
	StringUpper, vTextA, vTextA
	StringUpper, vTextB, vTextB
	if ("" vTextA = "" vTextB)
		return -vOffset

	oTempA := StrSplit(vTextA, "\")
	oTempB := StrSplit(vTextB, "\")
	vMin := oTempA.Length() < oTempB.Length() ? oTempA.Length() : oTempB.Length()

	Loop, % vMin
		if !(oTempA[A_Index] = oTempB[A_Index])
		{
			vTextA := oTempA[A_Index], vTextB := oTempB[A_Index], vIndex := A_Index
			break
		}

	if (vIndex = vMin) && (vTextA = vTextB)
		if (oTempA.Length() = vMin)
			return -1
		else if (oTempB.Length() = vMin)
			return 1

	vSCS := A_StringCaseSense
	StringCaseSense, On
	vRet := ("" vTextA) > ("" vTextB) ? 1 : ("" vTextA) < ("" vTextB) ? -1 : -vOffset
	StringCaseSense, % vSCS
	return vRet
}
Examples for getting a list of files, or a list of registry keys (via RegEdit), randomising the list, and then sorting.

Code: Select all

q:: ;sort paths by both orders
;vText := "A,A\A,A\B,A\C,B,B\A,B\B,B\C,C,C\A,C\B,C\C"
vText := "A,A\A,A\B,B,B\A,B\B,A\A\A,A\A\B,A\B\A,A\B\B,B\A\A,B\A\B,B\B\A,B\B\B"
vText := StrReplace(vText, ",", "`n")
Sort, vText, Random
Sort, vText, F JEE_SortPathFindNextFile
MsgBox, % vText
Sort, vText, F JEE_SortPathRegEdit
MsgBox, % vText
return

;==================================================

;q:: ;regedit - backup registry (you may get a User Account Control prompt for each root key)
vList := "HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_USERS,HKEY_CURRENT_CONFIG"

;e.g. sizes (MB):
;69	HKEY_CLASSES_ROOT
;47	HKEY_CURRENT_USER
;309	HKEY_LOCAL_MACHINE
;99	HKEY_USERS
;0	HKEY_CURRENT_CONFIG

vDir = %A_Desktop%
vNow := A_Now
Loop, Parse, vList, `,
{
	vRegKey := A_LoopField
	vTarget = %ComSpec% /c regedit /e "%vDir%\%vRegKey% %vNow%.hiv" %vRegKey%,, HIDE
	;MsgBox, % vTarget
	RunWait, %ComSpec% /c regedit /e "%vDir%\%vRegKey% %vNow%.hiv" %vRegKey%,, HIDE
}
MsgBox, % "done"
return

;==================================================

;q:: ;sort registry keys
vPathNeedle = %A_Desktop%\HKEY_CURRENT_CONFIG *.hiv
vPathNeedle = %A_Desktop%\HKEY_CURRENT_USER *.hiv
vPathNeedle = %A_Desktop%\HKEY_CLASSES_ROOT *.hiv
vPathNeedle = %A_Desktop%\HKEY_USERS *.hiv
vPathNeedle = %A_Desktop%\HKEY_LOCAL_MACHINE *.hiv
Loop, Files, % vPathNeedle, F
	vPath := A_LoopFileFullPath
if !FileExist(vPath)
{
	MsgBox, % "error: file not found:`r`n" vPathNeedle
	return
}
else
	MsgBox, % vPath

FileRead, vText, % vPath
vOutput := ""
VarSetCapacity(vOutput, 1000000*2)
vIsV1 := !!SubStr(1,0)
Loop, Parse, vText, `n, `r
{
	vTemp := A_LoopField
	if !(SubStr(vTemp, 1, 1) = "[") || !(SubStr(vTemp, vIsV1-1) = "]")
		continue
	vOutput .= SubStr(vTemp, 2, -1) "`n"
}

vOutput := SubStr(vOutput, 1, -1)
;MsgBox, % vOutput
vOutput2 := vOutput
Sort, vOutput2, Random
Sort, vOutput2, F JEE_SortPathRegEdit
;JEE_WinMergeCompareStrings("1`n" vOutput, "2`n" vOutput2)

MsgBox, % StrLen(vOutput)
MsgBox, % (vOutput = vOutput2)
return

;==================================================

;q:: ;sort paths
vDir1 = C:\Program Files
;vDir1 = %A_Desktop%
vOutput := ""
VarSetCapacity(vOutput, 1000000*2)
Loop, Files, % vDir1 "\*", FDR
	vOutput .= A_LoopFileFullPath "`n"
vOutput := SubStr(vOutput, 1, -1)
vOutput2 := vOutput
Sort, vOutput2, Random
Sort, vOutput2, F JEE_SortPathFindNextFile
;JEE_WinMergeCompareStrings(vOutput, vOutput2)

MsgBox, % StrLen(vOutput)
MsgBox, % (vOutput = vOutput2)
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask For Help”

Who is online

Users browsing this forum: au6, BushMange, howardb1, MannyKSoSo, VACO BenQ, w0z and 187 guests