// trolls the help extension help directories and compiles a doc with links
var path, doc, result, headingIndices, headingFont, excluded, addFunc;
var underlineStarts, underlineRanges, titleString, thirdParty, thirdPartyIndex;
var extensions, extensionsIndex, extensionFunc, extensionsRoots, extensionsFolders;
var undoc, undocIndex;
path = PathName.new("Help/");
headingIndices = List.new;
titleString = "A Generated List of all Documented Extension Classes";
undoc = "*Show All Undocumented Classes";
result = titleString ++ Char.nl ++ Char.nl ++ "Below is an automatically generated list of all documented extension classes (i.e. those whose class and help files are in /Library/Application Support/SuperCollider/Extensions or ~/Library/Application Support/SuperCollider/Extensions), sorted by directory.\n\nFor a list of undocumented classes click here:" + Char.tab;
undocIndex = result.size;
result = result ++ undoc ++ Char.nl ++ Char.nl;
// put included third party libraries at the end
excluded = [PathName("Help/crucial"), PathName("Help/JITLib")];
// this func trolls the directory and harvests the descriptions
addFunc = {|folderPathName|
var classFiles, heading, currentFile, currentFileString, temp;
classFiles = "";
folderPathName.files.do({|item|
var nameString, nameIndex, end;
nameString = item.fileName.split($.).at(0);
if(nameString.asSymbol.asClass.notNil, {
currentFile = File(item.fullPath, "r");
currentFileString = currentFile.readAllString;
// fix accent acute (remove it)
currentFileString.findAll("\'8").reverseDo({ |i|
currentFileString = currentFileString.copyFromStart(i-2) ++
currentFileString.copyToEnd(i+2);
});
currentFile.close;
// strip RTF gunk
currentFileString = currentFileString.stripRTF;
nameIndex = currentFileString.find(nameString);
if(nameIndex.notNil, {
currentFileString = currentFileString.drop(nameIndex);
end = currentFileString.find("\n");
if( end.notNil, {
end = end - 1;
currentFileString = currentFileString.copyFromStart(end);
});
// remove tab stops
currentFileString = currentFileString.reject({|item|item == $\t});
// remove commas, hyphens, and spaces
while({(currentFileString[nameString.size] == $,) ||
(currentFileString[nameString.size] == $ ) ||
(currentFileString[nameString.size] == $-)},
{currentFileString = currentFileString.copyFromStart(nameString.size -1) ++
currentFileString.copyToEnd(nameString.size + 1);
}
);
if(currentFileString.size > nameString.size, {
currentFileString = currentFileString.insert(nameString.size, "\t");
});},
{
currentFileString = nameString;
}
);
// add square brackets
currentFileString = currentFileString.insert(nameString.size, "]");
currentFileString = currentFileString.insert(0, "[");
classFiles = classFiles ++ Char.tab ++ currentFileString ++ Char.nl;
});
});
if(classFiles.size > 0, {
//heading = folderPathName.fileName;
heading = folderPathName.fullPath;
headingIndices.add([result.size, heading.size]);
result = result ++ heading ++ Char.nl ++ Char.nl ++ classFiles ++ Char.nl;
});
folderPathName.foldersWithoutCVS.do({|folder|
if(excluded.detect({|item| item.fileName == folder.fileName; }).isNil,
{addFunc.value(folder);}
);
});
};
//addFunc.value(path);
// Check for Extensions Folders and add if they exist
extensionsRoots = [PathName("/Library/Application Support/SuperCollider/Extensions"),
PathName("~/Library/Application Support/SuperCollider/Extensions")];
extensionsRoots.any({|item| item.pathMatch.size > 0 }).if({
extensionsFolders = List.new;
extensionFunc = { |path|
path.folders.do({|item|
item.fullPath.containsi("help").if({ extensionsFolders.add(item)},{
extensionFunc.value(item);});
});
};
extensionsRoots.do({|item| extensionFunc.value(item); });
result = result ++ "\n\n";
// result = result ++ "\n------------------------\n\n";
// extensions = "Extensions:";
// extensionsIndex = result.size;
// result = result ++ extensions + Char.nl + Char.nl;
extensionsFolders.do({|item| addFunc.value(item);});
});
// Third Party Libraries
//result = result ++ "\n------------------------\n\n";
//
//thirdParty = "Included Third Party Libraries:";
//thirdPartyIndex = result.size;
//
//result = result ++ thirdParty + Char.nl + Char.nl;
//
//excluded.do({|item| addFunc.value(item); result = result ++ "\n------------\n\n";});
//doc = Document.new("Documented Classes");
// this sets basic tab stops and line spacing
doc = Document.open(File.getcwd ++ "/" ++ "Help/help-scripts/tab-template.rtf");
doc.title = "Documented Extension Classes";
// set the fonts
doc.setFont(Font("Helvetica", 12));
doc.string = result;
doc.setFont(Font("Helvetica-Bold", 18), 0, titleString.size);
//doc.setFont(Font("Helvetica-Bold", 16), thirdPartyIndex, thirdParty.size);
extensionsIndex.notNil.if({
doc.setFont(Font("Helvetica-Bold", 16), extensionsIndex, extensions.size);
});
headingFont = Font("Helvetica-Bold", 14);
headingIndices.do({|item| doc.setFont(headingFont, *item)});
// find the underlines for help links. Apparently faster than storing them above.
underlineStarts = doc.string.findAll("[").reverse + 1;
underlineRanges = doc.string.findAll("]").reverse - underlineStarts;
underlineStarts.do({|item, i| doc.selectRange(item, underlineRanges[i]); doc.underlineSelection;});
doc.selectRange(undocIndex, undoc.size);
doc.underlineSelection;
doc.selectRange(0,0);
doc.editable_(false);
// keeps window title as it should be!
doc.mouseDownAction = { {doc.title = "Documented Classes";}.defer(0.00001) };
{doc.removeUndo;}.defer(0.001);