![]() ![]() |
Jul 10 2006, 10:54 AM Post
#1 | |
| MSFN Addict ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members Posts: 1760 Joined: 22-May 05 From: Paris Member No.: 57090 OS: none |
Hi everybody. For my own needs I coded an alphabetic sorter for WIHU. It has been harsh and I had to start it again from scratch but now it's ready. I've tested it a bit and all I can say is it's really nice. The thing was to use a recursive function with two parameters : the old "rank" and the new "rank". I always wondered why there was these stupid variables visibility rules but now, I enjoy them, no, I LOVE them : the function sorts a "level", enters the first sublevel it finds by calling itself, the sublevel is sorted and the apps goes back to the first level. Vocabulary: Index : the last value in description.x.y.z; here : z. Level : description.x.y.z.k where k changes, description.x.y.2.0, description.x.y.2.1, description.x.y.2.2, description.x.y.2.6, description.x.y.2.38 are in the same level (here .x.y.2), description.x.y.3.4 is not. Sublevel : .x.y.z.k.p where k changes. Here is the code (AutoHotKey): CODE ;#NoTrayIcon Loop, %0% { if (%A_Index% = "/CLEAN") CLEAN = 1 } Gui, Add, Text, y9, Input file : Gui, Add, Edit, vsource x15 w300 Gui, Add, Button, gBrowseInput x320 y27 w60, Browse Gui, Add, Text, x10, Output File : Gui, Add, Edit, vout x15 w300 Gui, Add, Button, gBrowseOutput x320 y74 w60, Browse Gui, Add, Text, x10, Maximal Index : Gui, Add, DDL, vmax w60 x15, 10|20|40|60|80||100|120|150|180|200 Gui, Add, Button, gRun x170 y144 w50, Run! ShowMain: Gui, Show return BrowseInput: Gui, +OwnDialogs FileSelectFile, source, 1, %A_ScriptDir%\install.ini, Please select the file to be sorted. GuiControl,, source, %source% Gui, Submit if (!out) { StringGetPos, pos, source, `\, R StringTrimRight, out, source, Strlen(source)-pos-1 GuiControl,, out, %out%\install_sorted.ini } Gui, Show return BrowseOutput: Gui, +OwnDialogs if (out) FileSelectFile, out, S2, %out%\install_sorted.ini, Please select where to place the file once sorted. else FileSelectFile, out, S2, %A_ScriptDir%\install_sorted.ini, Please select where to place the file once sorted. if (out) GuiControl,, out, %out% Gui, Show return Run: Gui, Submit Gui, +OwnDialogs IfNotExist, %source% { MsgBox, 0, Error!, Input file could not be found Goto, ShowMain } if (source=out) { MsgBox, 0, Error, Input and output files must be different!`r`nPlease change this. Goto, ShowMain } MsgBox, 0, Processing..., The script will take some time to complete.`r`nPlease press OK and wait. FileDelete, %out% Loop, Read, %A_ScriptDir%\sectionlist.txt ;parses sections to sort { section:=A_LoopReadLine Write("","", "description") ;calls the write function for each item (exceptionnal one) Write("", "", "command") Write("", "", "selected") Write("", "", "hidden") Write("", "", "collapsed") Write("", "", "locked") Write("", "", "disabled") Write("", "", "group") Write("", "", "flags") Write("", "", "workdir") Write("", "", "helptext") Write("", "", "ext_creator_switchtype") Write("", "", "ext_creator_switchtype") Sort() } Sort(oldlevel="", newlevel="") { ;the main function, recursively called Global max, source, out, section Loop, %max% { i:=A_Index - 1 ;WIHU's first index is 0 whereas AHK's one is 1 IniRead, iuv, %source%, %section%, description%oldlevel%.%i%, %A_Space% ;retrieves sections description if (iuv="") ;avoid adding non-existant indexes continue if (Names) ;appends a semi-column and the section name (iuv) with its old index (@i) to the list, except if ... Names:=Names ";" iuv "@" i else ;... except if the list is empty (would bug otherwise) Names:=iuv "@" i } Sort, Names, D`; StringSplit, Names, Names, `; Loop, %Names0% { i:=A_Index - 1 ;same as before : WIHU's first index is 0 whereas AHK's one is 1 Stringsplit, oldrank, Names%A_Index%, `@ ;retrieves old index Write(oldlevel "." oldrank2, newlevel "." i, "description") ;calls the write function for each item Write(oldlevel "." oldrank2, newlevel "." i, "command") Write(oldlevel "." oldrank2, newlevel "." i, "selected") Write(oldlevel "." oldrank2, newlevel "." i, "hidden") Write(oldlevel "." oldrank2, newlevel "." i, "collapsed") Write(oldlevel "." oldrank2, newlevel "." i, "locked") Write(oldlevel "." oldrank2, newlevel "." i, "disabled") Write(oldlevel "." oldrank2, newlevel "." i, "group") Write(oldlevel "." oldrank2, newlevel "." i, "flags") Write(oldlevel "." oldrank2, newlevel "." i, "workdir") Write(oldlevel "." oldrank2, newlevel "." i, "helptext") Write(oldlevel "." oldrank2, newlevel "." i, "ext_creator_switchtype") Write(oldlevel "." oldrank2, newlevel "." i, "ext_creator_originalcommand") IniRead, iuv, %source%, %section%, description%oldlevel%.%oldrank2%.0, %A_Space% ;is there a deeper level to sort ? if (iuv!="") Sort(oldlevel "." oldrank2, newlevel "." i) ;recursive call because when there is a deeper level } } FileRead, sorted, %out% ;needed for the three followig lines StringReplace, sorted, sorted, description, `r`ndescription, All ;adds linefeeds so the file can be read by an human StringReplace, sorted, sorted, [, `r`n[, All ;same StringReplace, sorted, sorted, ]`r`n, ], All ;removes some non-necessary linefeeds introduced just before StringReplace, sorted, sorted, `r`n[, [ ; removes the first linefeed FileDelete, %out% ;deletes the file so... FileAppend, %sorted%, %out% ;it can be 'overwritten' MsgBox, 0, Operation Complete, Input file has been sorted. GuiClose: ExitApp Write(old, new, var) { ;the function used to write in the ini global source, out, section, CLEAN IniRead, iuv, %source%, %section%, %var%%old%, %A_Space% ;retrieves the old value if (iuv or !CLEAN) ;keys with empty values are not copied over, should *maybe* be changed IniWrite, %iuv%, %out%, %section%, %var%%new% ;writes the new value } Limitations: -sublevels are only detected if there is a ".0" description : imagine you are at .0.2.1 level. If there is no "description.0.2.1.0" INI-key, then the sublevel will not be seen or sorted; this could lead to some problems, take care! (first level is an exception : description.0 will always be seen) -it is not possible to have "@" character inside the description of an item. This can be changed but there will always be a forbidden character : ù or µ or $ or ¤ or £ or # or § .... -Unicode files are not supported yet : output files will always be in ANSI format. As far as I'm concerned I have no need for this but if someone does, please let me, I'll work on it. Features:
Run the app once, a file called "sectionlist.txt" will be created in the app's dir. Fill it according to what I said previously. The script is holly fast; my previous try (which was not working btw) was MUCH longer, this one needs less than 10 seconds to go through a 3000 lines install.ini (created with the .Net app I don't remember the name). Note that sorting only starts once you've clicked "OK". TODO: -Unicode support -let the user decide in which order entries should be placed (with "Sort" and "Sort along with all sublevels" buttons) -add an editor inside the app instead of sectionlist.txt Download This post has been edited by Camarade_Tux: Aug 12 2006, 09:06 AM |
| | |
Jul 13 2006, 03:32 PM Post
#2 | |
| Developer ![]() ![]() ![]() ![]() Group: Members Posts: 609 Joined: 8-June 04 From: Bad Kreuznach Member No.: 22118 |
Hi Camarade_Tux, many thanks for your work ... I know you were very busy at school. I'm sure there are some users who may use your tool. Benjamin Kalytta |
| | |
Jul 14 2006, 03:27 PM Post
#3 | |
| MSFN Addict ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members Posts: 1760 Joined: 22-May 05 From: Paris Member No.: 57090 OS: none |
Indeed I was busy but now exams are over. ^^ Also, I've added two things : abort if sectionlist.txt can not be found and do not add non-existing entries in the INI if they were not already there. The drawback for the second feature is "ù" can not be used as a value for any entry of install.ini (but aùa and even ùù can still be used). 30 minutes ago there was to be a third feature but I've forgotten what it was. .... Must be too old. And coding this app has on its own been lots of fun. Updated sourcecode: (no bin as I don't have the AHK compiler here) CODE ;#NoTrayIcon IfNotExist, %A_ScriptDir%\SectionList.txt { MsgBox, 0, Fatal Error, SectionList.txt could not be found`, check this file is present and try again! ExitApp } Loop, %0% { if (%A_Index% = "/CLEAN") CLEAN = 1 } Gui, Add, Text, y9, Input file : Gui, Add, Edit, vsource x15 w300 Gui, Add, Button, gBrowseInput x320 y27 w60, Browse Gui, Add, Text, x10, Output File : Gui, Add, Edit, vout x15 w300 Gui, Add, Button, gBrowseOutput x320 y74 w60, Browse Gui, Add, Text, x10, Maximal Index : Gui, Add, DDL, vmax w60 x15, 10|20|40|60|80||100|120|150|180|200 Gui, Add, Button, gRun x170 y144 w50, Run! ShowMain: Gui, Show return BrowseInput: Gui, +OwnDialogs FileSelectFile, source, 1, %A_ScriptDir%\install.ini, Please select the file to be sorted. GuiControl,, source, %source% Gui, Submit if (!out) { StringGetPos, pos, source, `\, R StringTrimRight, out, source, Strlen(source)-pos-1 GuiControl,, out, %out%\install_sorted.ini } Gui, Show return BrowseOutput: Gui, +OwnDialogs if (out) FileSelectFile, out, S2, %out%\install_sorted.ini, Please select where to place the file once sorted. else FileSelectFile, out, S2, %A_ScriptDir%\install_sorted.ini, Please select where to place the file once sorted. if (out) GuiControl,, out, %out% Gui, Show return Run: Gui, Submit Gui, +OwnDialogs IfNotExist, %source% { MsgBox, 0, Error!, Input file could not be found Goto, ShowMain } if (source=out) { MsgBox, 0, Error, Input and output files must be different!`r`nPlease change this. Goto, ShowMain } MsgBox, 0, Processing..., The script will take some time to complete.`r`nPlease press OK and wait. FileDelete, %out% Loop, Read, %A_ScriptDir%\sectionlist.txt ;parses sections to sort { section:=A_LoopReadLine Write("","", "description") ;calls the write function for each item (exceptionnal one) Write("", "", "command") Write("", "", "selected") Write("", "", "hidden") Write("", "", "collapsed") Write("", "", "locked") Write("", "", "disabled") Write("", "", "group") Write("", "", "flags") Write("", "", "workdir") Write("", "", "helptext") Write("", "", "ext_creator_switchtype") Write("", "", "ext_creator_switchtype") Sort() } Sort(oldlevel="", newlevel="") { ;the main function, recursively called Global max, source, out, section Loop, %max% { i:=A_Index - 1 ;WIHU's first index is 0 whereas AHK's one is 1 IniRead, iuv, %source%, %section%, description%oldlevel%.%i%, %A_Space% ;retrieves sections description if (iuv="") ;avoid adding non-existant indexes continue if (Names) ;appends a semi-column and the section name (iuv) with its old index (@i) to the list, except if ... Names:=Names ";" iuv "@" i else ;... except if the list is empty (would bug otherwise) Names:=iuv "@" i } Sort, Names, D`; StringSplit, Names, Names, `; Loop, %Names0% { i:=A_Index - 1 ;same as before : WIHU's first index is 0 whereas AHK's one is 1 Stringsplit, oldrank, Names%A_Index%, `@ ;retrieves old index Write(oldlevel "." oldrank2, newlevel "." i, "description") ;calls the write function for each item Write(oldlevel "." oldrank2, newlevel "." i, "command") Write(oldlevel "." oldrank2, newlevel "." i, "selected") Write(oldlevel "." oldrank2, newlevel "." i, "hidden") Write(oldlevel "." oldrank2, newlevel "." i, "collapsed") Write(oldlevel "." oldrank2, newlevel "." i, "locked") Write(oldlevel "." oldrank2, newlevel "." i, "disabled") Write(oldlevel "." oldrank2, newlevel "." i, "group") Write(oldlevel "." oldrank2, newlevel "." i, "flags") Write(oldlevel "." oldrank2, newlevel "." i, "workdir") Write(oldlevel "." oldrank2, newlevel "." i, "helptext") Write(oldlevel "." oldrank2, newlevel "." i, "ext_creator_switchtype") Write(oldlevel "." oldrank2, newlevel "." i, "ext_creator_originalcommand") IniRead, iuv, %source%, %section%, description%oldlevel%.%oldrank2%.0, %A_Space% ;is there a deeper level to sort ? if (iuv!="") Sort(oldlevel "." oldrank2, newlevel "." i) ;recursive call because when there is a deeper level } } FileRead, sorted, %out% ;needed for the three followig lines StringReplace, sorted, sorted, description, `r`ndescription, All ;adds linefeeds so the file can be read by an human StringReplace, sorted, sorted, [, `r`n[, All ;same StringReplace, sorted, sorted, ]`r`n, ], All ;removes some non-necessary linefeeds introduced just before StringReplace, sorted, sorted, `r`n[, [ ; removes the first linefeed FileDelete, %out% ;deletes the file so... FileAppend, %sorted%, %out% ;it can be 'overwritten' MsgBox, 0, Operation Complete, Input file has been sorted. GuiClose: ExitApp Write(old, new, var) { ;the function used to write in the ini global source, out, section, CLEAN IniRead, iuv, %source%, %section%, %var%%old%, ù ;retrieves the old value if (iuv!="ù" or !CLEAN) ;keys with empty values are not copied over, should *maybe* be changed IniWrite, %iuv%, %out%, %section%, %var%%new% ;writes the new value } |
| | |
Aug 12 2006, 09:08 AM Post
#4 | |
| MSFN Addict ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members Posts: 1760 Joined: 22-May 05 From: Paris Member No.: 57090 OS: none |
Updated! What's new: Features:
CODE #NoTrayIcon IfNotExist, %A_ScriptDir%\SectionList.txt { IniWrite, %blank_var%, %A_ScriptDir%\sectionlist.txt, main, list IniWrite, %blank_var%, %A_ScriptDir%\sectionlist.txt, main, SectionSort IniWrite, %blank_var%, %A_ScriptDir%\sectionlist.txt, main, clean_level IniWrite, %blank_var%, %A_ScriptDir%\sectionlist.txt, main, Sort IniWrite, %blank_var%, %A_ScriptDir%\sectionlist.txt, main, special_dark MsgBox, 0, Fatal Error, SectionList.txt could not be found`, check this file is present and try again! ExitApp } IniRead, sectionlist, %A_ScriptDir%\sectionlist.txt, main, list, 0 if !sectionlist { MsgBox, 0 Fatal Error, Sectionlist.txt does not contain the names of the sections to sort! ExitApp } IniRead, SortSections, %A_ScriptDir%\sectionlist.txt, main, SectionSort, 1 if (SortSections) Sort, sectionlist, D`; IniRead, input, %A_ScriptDir%\sectionlist.txt, main, input, %A_Space% IniRead, output, %A_ScriptDir%\sectionlist.txt, main, output, %A_Space% Gui, Add, Text, y9, Input file : Gui, Add, Edit, vsource x15 w300, %input% Gui, Add, Button, gBrowseInput x320 y27 w60, Browse Gui, Add, Text, x10, Output File : Gui, Add, Edit, vout x15 w300, %output% Gui, Add, Button, gBrowseOutput x320 y74 w60, Browse Gui, Add, Text, x10, Maximal Index : Gui, Add, DDL, vmax w60 x15, 10|20|40|60|80||100|120|150|180|200 Gui, Add, Button, gRun x170 y144 w50, Run! ShowMain: Gui, Show return BrowseInput: Gui, +OwnDialogs FileSelectFile, source, 1, %input%, Please select the file to be sorted. GuiControl,, source, %source% Gui, Submit if (!out AND !output) { StringGetPos, pos, source, `\, R StringTrimRight, out, source, Strlen(source)-pos GuiControl,, out, %out%\install_sorted.ini } Gui, Show return BrowseOutput: Gui, +OwnDialogs if (out) FileSelectFile, out, S2, %out%\install_sorted.ini, Please select where to place the file once sorted. else FileSelectFile, out, S2, %output%, Please select where to place the file once sorted. if (out) GuiControl,, out, %out% Gui, Show return Run: Gui, Submit Gui, +OwnDialogs IfNotExist, %source% { MsgBox, 0, Error!, Input file could not be found Goto, ShowMain } if (source=out) { MsgBox, 0, Error, Input and output files must be different!`r`nPlease change this. Goto, ShowMain } MsgBox, 0, Processing..., The script will take some time to complete.`r`nPlease press OK and wait. IniWrite, %source%, %A_ScriptDir%\sectionlist.txt, main, input IniWrite, %out%, %A_ScriptDir%\sectionlist.txt, main, output FileDelete, %out% Loop, Parse, sectionlist, `;;parses sections to sort { section:=A_LoopField IniRead, clean_level, %A_ScriptDir%\sectionlist.txt, %section%, clean_level, ù if (clean_level="ù") { IniRead, clean_level, %A_ScriptDir%\sectionlist.txt, main, clean_level, ù if (clean_level="ù") { IniWrite, 0, %A_ScriptDir%\sectionlist.txt, main, clean_level IniWrite, 0, %A_ScriptDir%\sectionlist.txt, %section%, clean_level clean_level=0 } else IniWrite, %clean_level%, %A_ScriptDir%\sectionlist.txt, %section%, clean_level } IniRead, Sort, %A_ScriptDir%\sectionlist.txt, %section%, Sort, ù if (Sort="ù") { IniRead, Sort, %A_ScriptDir%\sectionlist.txt, main, Sort, ù if (Sort="ù") { IniWrite, 0, %A_ScriptDir%\sectionlist.txt, main, Sort IniWrite, 0, %A_ScriptDir%\sectionlist.txt, %section%, Sort Sort=0 } else IniWrite, %Sort%, %A_ScriptDir%\sectionlist.txt, %section%, Sort } IniRead, special_dark, %A_ScriptDir%\sectionlist.txt, %section%, special_dark, ù if (special_dark="ù") { IniRead, special_dark, %A_ScriptDir%\sectionlist.txt, main, special_dark, ù if (special_dark="ù") { IniWrite, 0, %A_ScriptDir%\sectionlist.txt, main, special_dark IniWrite, 0, %A_ScriptDir%\sectionlist.txt, %section%, special_dark special_dark=0 } else IniWrite, %special_dark%, %A_ScriptDir%\sectionlist.txt, %section%, special_dark } Write("","", "description");calls the write function for each item (exceptionnal one) Write("", "", "command") Write("", "", "selected") Write("", "", "hidden") Write("", "", "collapsed") Write("", "", "locked") Write("", "", "disabled") Write("", "", "group") Write("", "", "flags") Write("", "", "workdir") Write("", "", "helptext") Write("", "", "ext_creator_switchtype") Write("", "", "ext_creator_originalcommand") Sort() } Sort(oldlevel="", newlevel="") {;the main function, recursively called Global max, source, out, section, Sort, special_dark Loop, %max% { i:=A_Index - 1;WIHU's first index is 0 whereas AHK's one is 1 IniRead, iuv, %source%, %section%, description%oldlevel%.%i%, %A_Space%;retrieves sections description if (iuv="");avoid adding non-existant indexes continue if (Names);appends a semi-column and the section name (iuv) with its old index (@i) to the list, except if ... Names:=Names ";" iuv "@" i else;... except if the list is still empty (would bug otherwise) Names:=iuv "@" i } if (Sort) Sort, Names, D`; StringSplit, Names, Names, `; Loop, %Names0% { i:=A_Index - 1;same as before : WIHU's first index is 0 whereas AHK's one is 1 Stringsplit, oldrank, Names%A_Index%, `@;retrieves old index Write(oldlevel "." oldrank2, newlevel "." i, "description");calls the write function for each item Write(oldlevel "." oldrank2, newlevel "." i, "command") Write(oldlevel "." oldrank2, newlevel "." i, "selected") Write(oldlevel "." oldrank2, newlevel "." i, "hidden") Write(oldlevel "." oldrank2, newlevel "." i, "collapsed") Write(oldlevel "." oldrank2, newlevel "." i, "locked") Write(oldlevel "." oldrank2, newlevel "." i, "disabled") Write(oldlevel "." oldrank2, newlevel "." i, "group") Write(oldlevel "." oldrank2, newlevel "." i, "flags") Write(oldlevel "." oldrank2, newlevel "." i, "workdir") Write(oldlevel "." oldrank2, newlevel "." i, "helptext") Write(oldlevel "." oldrank2, newlevel "." i, "ext_creator_switchtype") Write(oldlevel "." oldrank2, newlevel "." i, "ext_creator_originalcommand") IniRead, iuv, %source%, %section%, description%oldlevel%.%oldrank2%.0, %A_Space%;is there a deeper level to sort ? if (iuv!="") Sort(oldlevel "." oldrank2, newlevel "." i);recursive call because when there is a deeper level } } FileRead, sorted, %out%;needed for the three followig lines StringReplace, sorted, sorted, description, `r`ndescription, All;adds linefeeds so the file can be read by an human StringReplace, sorted, sorted, [, `r`n[, All;same StringReplace, sorted, sorted, ]`r`n, ], All;removes some non-necessary linefeeds introduced just before StringReplace, sorted, sorted, `r`n[, [; removes the first linefeed FileDelete, %out%;deletes the file so... FileAppend, %sorted%, %out%;it can be 'overwritten' MsgBox, 0, Operation Complete, Input file has been sorted. GuiClose: ExitApp Write(old, new, var) {;the function used to write in the ini global source, out, section, clean_level IniRead, iuv, %source%, %section%, %var%%old%, ù;retrieves the value at the old position ;if (clean_level="-1") {;if you want to bloat your file, not available ATM ; if (iuv="ù") ; iuv=0 ; IniWrite, %blank_var%, %out%, %section%, %var%%new% if (clean_level="0" AND iuv!="ù");keys with empty values are not copied over, should *maybe* be changed IniWrite, %iuv%, %out%, %section%, %var%%new%;writes the new value if (clean_level="1" AND iuv!="ù" AND iuv);keys with empty values are not copied over, should *maybe* be changed IniWrite, %iuv%, %out%, %section%, %var%%new%;writes the new value } This post has been edited by Camarade_Tux: Aug 12 2006, 09:08 AM |
| | |
May 25 2008, 04:39 AM Post
#5 | |
| Newbie Group: Members Posts: 13 Joined: 10-October 05 Member No.: 76246 |
it's not good to have the old script in the first entry, but the description of the newest version. i was a little bit confused, why [main]list=x;y;z doesnt work with the script from the same post :-) here's is my quick'n'dirty change based on the version from the start post with following features: * thanks to Camarade_Tux! * warns if a command without a description exists cause this item would be deleted * copies and sorts entries from the default sections [Environment], [users], [Settings] to the beginning of the file * sorts sections and sections keys and indents the keys * deletes useless keys * very basic syntax checker * full automatic -->no settingsfile used script: http://www.autohotkey.net/~ladiko/WIHU_Sor...WIHU_Sorter.ahk executable: http://www.autohotkey.net/~ladiko/WIHU_Sor...WIHU_Sorter.exe This post has been edited by ladiko: May 25 2008, 07:18 AM |
| | |
![]() ![]() |
| Lo-Fi Version | Time is now: 7th November 2009 - 02:02 PM |