Script to sort module docs into folders alphabetically Thread last updated on 2006-06-13 21:12:49

Posted by member 5575 on 2004-08-22 01:48:05

'===============================================================================
' sortDocs.vbs
' - A script to organize module documentation (files and folders) alphabetically
' so that the documentation menu doesn't grow outrageously large. Point this
' script at your module docs folder by:
' 1) Dragging the folder onto the script in the file manager
' 2) Input the docs root folder through a dialog box
' 3) Command line, e.g., wscript sortDocs.vbs "C:\Litestep\modules\docs"
'===============================================================================

Dim FSO, ScriptDir, RootDir, OutputFile
Dim LastSlash, FolderName, contents

Set FSO = CreateObject("Scripting.FileSystemObject")
ScriptDir = FSO.GetFile(Wscript.ScriptFullName).ParentFolder

'-- RootDir - top of docs file hierarchy. Initialized only here - input below.

RootDir = ""

'--- Get folder dropped on script or use InputBox:

If WScript.Arguments.count > 0 Then
RootDir = WScript.Arguments.item(0)
Else
Do while Len(RootDir) = 0
RootDir = InputBox("Enter path to docs folder", "Select docs folder")
Loop
End If

If (not FSO.FolderExists(RootDir)) Then
msgbox "Unable to locate input folder:"&_
vbcrlf&vbcrlf&RootDir&_
vbcrlf&vbcrlf&"Exiting."
Set FSO = Nothing
WScript.Quit
End If

'--- Strip trailing slash, and check to make sure the input is a folder and not
'--- a drive root, e.g., "M:\". The folder recursion doesn't tolerate that. =(

If (Right(RootDir,1) = "\") Then
If (Len(RootDir) = 3) Then
msgbox "Unable to recurse drive root - sorry!"&_
vbcrlf&vbcrlf&"Exiting."
Set FSO = Nothing
WScript.Quit
End If
RootDir = Left(RootDir,Len(RootDir)-1)
End If

'--- Truncate path to last folder name.

LastSlash = InStrRev(RootDir,"\",-1,1)
FolderName = Right(RootDir,Len(RootDir)-LastSlash)
Set OutputFile = FSO.CreateTextFile(ScriptDir&"\"&FolderName&".txt")

'--- Recursively scan the folder and organize it

sortFolder RootDir

'--- That's it.

Set OutputFile = Nothing
Set FSO = Nothing

Wscript.Quit

'===============================================================================
'===============================================================================

sub sortFolder(InputFolder)
Dim ThisFolder, TheseSubs

'----- Open the parent folder

Set ThisFolder = FSO.GetFolder(InputFolder)
Set TheseSubs = ThisFolder.SubFolders

'--- Process files in this folder

If ThisFolder.Files.Count 0 Then
For each File in ThisFolder.Files
If (isDocs(File.Name)) Then
firstLetter = Lcase(Left(File.Name,1))
destFolder = InputFolder&"\"&firstLetter&"\"
If (not FSO.FolderExists(destFolder)) Then
OutputFile.WriteLine("Creating folder: "&destFolder)
set dest = FSO.CreateFolder(destFolder)
End If
destPath = destFolder&File.Name
If (not FSO.FileExists(destPath)) Then
OutputFile.WriteLine("Moving file: "&File.Path&" -> "&destFolder)
FSO.MoveFile File.Path, destFolder
Else
msgbox "File already exists:"&vbcrlf&vbcrlf&destPath&vbcrlf&vbcrlf&_
"Deleting duplicate:"&vbcrlf&vbcrlf&File.Path
FSO.DeleteFile File.Path
End If
End If
Next
End If

'--- Process subfolders

If TheseSubs.Count 0 Then
For each Folder in TheseSubs
If (isDocs(Folder.Name)) Then
firstLetter = Lcase(Left(Folder.Name,1))
destFolder = InputFolder&"\"&firstLetter&"\"
If (not FSO.FolderExists(destFolder)) Then
OutputFile.WriteLine("Creating folder: "&destFolder)
set dest = FSO.CreateFolder(destFolder)
End If
OutputFile.WriteLine("Moving folder: "&Folder.Path&" -> "&destFolder)
FSO.MoveFolder Folder.Path, destFolder
End If
Next
End If

Set ThisFolder = Nothing
Set TheseSubs = Nothing

end sub 'sortFolder

'===============================================================================
' Function to determine whether a given file is 'docs'. Edit the file name
' matching rules below as you see fit. Currently we assume everything in that
' folder is docs if its name is more than one character long; single characters
' (a-z) are used for the names of the folders into which the docs are sorted.
'===============================================================================

function isDocs(Name)

isDocs = false

If ( Len(Name) > 1 ) Then
isDocs = true
End If

end function 'isDocs

Posted by member 5575 on 2004-08-22 01:49:27 link

Well, the code *used* to be indented nicely. I think the forum gollywogs ate my whitespace.

Posted by member 103254 on 2004-08-22 11:59:02 link

just use the [code tags , it'll display properly ;)

Posted by member 12025 on 2004-08-22 14:17:59 link

No, even the CODE tags remove indents.

Posted by member 7991 on 2004-08-22 22:21:01 link

ERROR

Window Title: "Windows Script Host"


Script: C:\LiteStep\modules\SortDocs.vbs
Line: 72
Char: 27
Error: Expected 'Then'
Code: 800A03F9
Source: Microsoft VBScript compilation error

Posted by member 99 on 2004-08-23 00:09:04 link

Ignore my post if you use Win9x.

You and your VB mumbo-jumbo! This is guaranteed to delete all of your files while trying to sort them:
@echo off
setlocal
if errorlevel 1 goto noluck

:: strip quotes
set ROOT=%1.
if %ROOT:~0,1%.%ROOT:~0,1%=="." set ROOT=%ROOT:~1,-1%
set ROOT=%ROOT:~0,-1%
:: ask for the root if we weren't told
if "%ROOT%"=="" (
set /P ROOT=Enter root folder or drag^&drop here:
)
:: strip quotes
set ROOT=%ROOT%.
if %ROOT:~0,1%.%ROOT:~0,1%=="." set ROOT=%ROOT:~1,-1%
set ROOT=%ROOT:~0,-1%
:: quit if they really aren't talking
if "%ROOT%"=="" goto :eof

pushd "%ROOT%"
if errorlevel 1 goto baddir

:: do the stuff
for /D %%d in (*) do call :move %%d
for %%d in (*) do call :move %%d

popd
goto :eof

:baddir
echo "%ROOT%"
goto :eof

:move
set WHAT=%*
:: skip 1-char long names
if "%WHAT:~1,1%"=="" goto :eof
:: make the section if it doesn't exist
if not exist "%WHAT:~0,1%" md "%WHAT:~0,1%"
:: brush your teeth
move "%WHAT%" "%WHAT:~0,1%\%WHAT%" > NUL
goto :eof

:noluck
echo Sorry, your OS isn't special enough.
Let me know if it doesn't work.

Seriously though, that is an excellent idea. Note that my batch file will not sort subdirectories. (say, anybody up for a mzscript version? ;)

Posted by member 37809 on 2004-08-23 07:26:12 link

Boreas forgot to replace occurrences of < with <
...
RabidCow's batch file works.

Posted by member 7991 on 2004-08-23 14:44:28 link

@rabid: Sexcellent, works great.

Posted by member 5575 on 2004-08-23 19:54:21 link

Ah - yeah, I just pasted the code straight from the script, and since VBscript uses
< and >
for comparisons, they got eaten - well except for one I see in the top level routine. Odd, that. My script doesn't sort subdirectories either, since some modules come with subfolders of stuff and I wanted to leave them as they were. It sure cleans up the hundreds of files in that top level, though. But batch files? Eeeeewwww =)

Posted by member 99 on 2004-08-25 03:01:25 link

Well, without indentation and written in VB, I saw "folder recursion" and guessed from there... at least with batch there's no indentation to lose. ;)

btw, if you decide that some sorted folder, say 'l', needs to be sorted further, you can adjust the length of the prefix it chops off and run it again on that subfolder. Something like:
:move
set WHAT=%*
:: skip 4-char long names
if "%WHAT:~4,1%"=="" goto :eof
:: make the section if it doesn't exist
if not exist "%WHAT:~0,4%" md "%WHAT:~0,4%"
:: brush your teeth
move "%WHAT%" "%WHAT:~0,4%\%WHAT%" > NUL
goto :eof

Posted by member 5575 on 2004-08-26 13:28:39 link

The recursion comment was actually left over from the "ancestral" script to this one. That one did, in fact, do recursion. My mp3 player can "read" the folder names to you in a synthesized voice as long as you put tiny little mp3 clips in each folder containing the name. I have a script that uses SAPI5 to generate and/or update those clips, and it does recursion *all* the way down - genre, artist, album, etc. It's a great feature for choosing albums or playlists while driving on a busy freeway!

Posted by member 99 on 2004-08-28 05:21:11 link

A variation on this idea, this will look for every module (in a given folder) that you have more than one set of documentation for (eg, popup2-2.1.3, popup2-2.1.7 are both popup2) and move them to a new subdirectory named after that module:
@echo off
setlocal
if errorlevel 1 goto noluck

:: strip quotes
set ROOT=%1.
if %ROOT:~0,1%.%ROOT:~0,1%=="." set ROOT=%ROOT:~1,-1%
set ROOT=%ROOT:~0,-1%
:: ask for the root if we weren't told
if "%ROOT%"=="" (
set /P ROOT=Enter root folder or drag^&drop here:
)
:: strip quotes
set ROOT=%ROOT%.
if %ROOT:~0,1%.%ROOT:~0,1%=="." set ROOT=%ROOT:~1,-1%
set ROOT=%ROOT:~0,-1%
:: quit if they really aren't talking
if "%ROOT%"=="" goto :eof

pushd "%ROOT%"
if errorlevel 1 goto baddir

:: send the module names to :move, may get duplicates
for /F "tokens=1,2 delims=-" %%F in ('dir/b') do (
call :move %%F %%G
)

popd
goto :eof

:baddir
echo "%ROOT%"
goto :eof

:move
:: did it really have a -?
if "%2"=="" goto re-sort
set MODULE=%1
:: have we seen this guy before?
for /F "tokens=1 delims==" %%V in ('set') do (
if "%%V"=="%MODULE%" goto second_time
)
set %MODULE%=That's one...
goto :eof
:second_time
:: there's at least two of them, so put them in a subdir
:: make the section if it doesn't exist
if not exist "%MODULE%" md "%MODULE%"
:re-sort
:: brush your teeth
for /F %%H in ('dir/b "%MODULE%-*" 2^>NUL') do (
move "%%H" "%MODULE%" > NUL
)
goto :eof

:noluck
echo Sorry, your OS isn't special enough.

Posted by member 5575 on 2004-08-28 17:27:42 link

Ooooh, man, you are upping the ante now. I can't wait until you get that batch file to *read* the docs - I'm pretty sure I can do that with SAPI5 and VBSCript. I'm also pretty sure that it's a horrible and useless thing to do in the first place.

Posted by member 99 on 2004-08-28 19:37:29 link

hmm, maybe if you broke the words into phonemes and "copy"ed together sound samples...

Posted by member 37809 on 2006-06-13 21:12:49 link

*boost*

I took a foray into JScript yesterday and this is what I came up with;
it will sort module docs into subdirs like this:

r\rarrr\0.1pre.html
s\simplemod\0.2.txt
m\modulename\ver.si.on\has.txt
m\modulename\ver.si.on\many.png
m\modulename\ver.si.on\files.html

I chose this format for use with a PopupDynamicFolder.
// this goes in \litestep\modules\docs\sortdocs.js
s=new ActiveXObject('Scripting.FileSystemObject')
n=0
a={}
r=s.GetFolder('.')
b='\\\\'
for(e=new Enumerator(r.subfolders);!e.atEnd();e.moveNext())a[n++]=e.item()
for(e=new Enumerator(r.files);!e.atEnd();e.moveNext())a[n++]={f:e.item()}
for(f in a){f=a[f]
e=f.f
f=e?e:f
n=f.name
if(m=n.match(/([^-]+)-(.+)/)){
s.FolderExists(c=r.path+b+n.charAt(0))?0:s.CreateFolder(c)
s.FolderExists(c+=b+m[1])?0:s.CreateFolder(c)
c+=b+m[2]
e?s.FileExists(c)?0:f.move(c):s.FolderExists(c)?0:f.move(c)}}


The code is meant to be compressed rather than obfuscated. guess I got bored.

EDIT: I lied. Obfuscation seems like an act of desperation, when done manually. Let's be proper now:
// this goes in \litestep\modules\docs\sortdocs.js
var fso = new ActiveXObject('Scripting.FileSystemObject');
var todo = [];
var e, root = fso.GetFolder('.');

e = new Enumerator(root.subfolders);
for (e.moveFirst(); !e.atEnd(); e.moveNext()) {
&nbsp;&nbsp;todo.push({ item: e.item() });
}
e = new Enumerator(root.files);
for (e.moveFirst(); !e.atEnd(); e.moveNext()) {
&nbsp;&nbsp;todo.push({ item: e.item(), is_file:1 });
}

for (var i=0, item; item = todo[i]; i++) {
&nbsp;&nbsp;var caps, dest, file = item.item;
&nbsp;&nbsp;if (caps = file.name.match(/([^-]+)-(.+)/)) {
&nbsp;&nbsp;&nbsp;&nbsp;dest = root.path +'\\\\'+ file.name.charAt(0);
&nbsp;&nbsp;&nbsp;&nbsp;if (!fso.FolderExists(dest)) fso.CreateFolder(dest);
&nbsp;&nbsp;&nbsp;&nbsp;dest += '\\\\'+ caps[1];
&nbsp;&nbsp;&nbsp;&nbsp;if (!fso.FolderExists(dest)) fso.CreateFolder(dest);
&nbsp;&nbsp;&nbsp;&nbsp;dest += '\\\\'+ caps[2];
&nbsp;&nbsp;&nbsp;&nbsp;if (item.is_file) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!fso.FileExists(dest)) file.move(dest);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else if (!fso.FolderExists(dest)) file.move(dest);
&nbsp;&nbsp;}
}