<#@ template language="C#" hostSpecific="true" #> <#@ assembly name="System.Core.dll" #> <#@ assembly name="System.dll" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Globalization" #> <#@ import namespace="System.Text.RegularExpressions" #> <# var sourceFolders = new string[] { "CompiledContent/bin/DesktopGL", "Content" }; #> namespace Nez { class Content { <# // loop through all of our sourceFolders foreach( var sourceFolder in sourceFolders ) { var directories = Directory.GetDirectories( sourceFolder ); // loop through all the directories in our sourceFolder foreach( var dir in directories ) { var dirName = new DirectoryInfo( dir ).Name.ToLower(); if( dirName == "bin" || dirName == "obj" || dirName == "content" ) continue; // dont delve into directories that don't contan xnb files var xnbFiles = Directory.GetFiles( dir, "*.xnb", SearchOption.AllDirectories ); if( xnbFiles.Length == 0 ) continue; // start off the recursive directory printing printDirectoryClass( dir, 2, sourceFolder ); } // handle any files in the root sourceFolder printContentFiles( sourceFolder, 2, sourceFolder ); } #> } } <#+ // all the valid file extensions we should add to the output file private string[] fileExtensionsToCopy = new string[] { ".xnb", ".png", ".ogg", ".wav", ".fxb" }; // C# reserved keywords private System.Collections.Generic.List keywords = new System.Collections.Generic.List { "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while" }; // recursively creates a class for each directory void printDirectoryClass( string dir, int depth, string sourceFolder ) { var dirInfo = new DirectoryInfo( dir ); var firstIndent = new string( ' ', depth * 4 ); var className = generateClassName( dirInfo.Name, true ); WriteLine( "{0}public static class {1}\n{2}{{", firstIndent, className, firstIndent ); // handle subdirectories foreach( var subdir in Directory.GetDirectories( dir ) ) printDirectoryClass( subdir, depth + 1, sourceFolder ); // handle files printContentFiles( dir, depth + 1, sourceFolder ); WriteLine( "{0}}}\n", firstIndent ); } // prints a const string for each file in the directory void printContentFiles( string dir, int depth, string sourceFolder ) { var firstIndent = new string( ' ', depth * 4 ); var files = Directory.EnumerateFiles( dir ) .Where( s => Array.IndexOf( fileExtensionsToCopy, Path.GetExtension( s ) ) >= 0 ); foreach( var file in files ) { // clear out all of the path up to the sourceFolder so we get just the relative path to the Content folder var finalPath = file.Substring( file.IndexOf( sourceFolder ) + sourceFolder.Length ); var fileInfo = new FileInfo( file ); var fileName = fileInfo.Name.Replace( ".xnb", string.Empty ); var className = generateClassName( fileName, false ); if( finalPath[0] == '/' || finalPath[0] == '\\' ) finalPath = finalPath.Substring( 1 ); // if file name is reserved insert a leading '@' if( keywords.Contains( className ) ) className = className.Insert( 0, "@" ); WriteLine( "{0}public const string {1} = @\"{2}\";", firstIndent, className, finalPath ); } } string stripInvalidPathChars( string input ) { var invalidChars = Path.GetInvalidPathChars(); return new string( input.Where( m => !invalidChars.Contains( m ) ).ToArray() ); } string stripInvalidFilenameChars( string input ) { var invalidChars = Path.GetInvalidFileNameChars(); return new string( input.Where( m => !invalidChars.Contains( m ) ).ToArray() ); } // attempts to generate a proper path name string generateClassName( string className, bool uppercaseFirstChar ) { // handle upper or lower casing the first char in the className if( uppercaseFirstChar && char.IsLower( className[0] ) ) className = char.ToUpper( className[0] ) + className.Substring( 1 ); else if( !uppercaseFirstChar && char.IsUpper( className[0] ) ) className = char.ToLower( className[0] ) + className.Substring( 1 ); // remove invalid characters var regex = new Regex( @"[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Nl}\p{Mn}\p{Mc}\p{Cf}\p{Pc}\p{Lm}]" ); className = regex.Replace( className, "" ); // class name doesn't begin with a letter, insert an underscore if( !char.IsLetter( className, 0 ) ) className = className.Insert( 0, "_" ); return className.Replace( " ", string.Empty ); } #>