úÎ_Æ^     7Supports bulk renaming of directories and files into a , standard, normalized format. portable Experimental(Calvin Smith <cs-haskell@protempore.net> 3The state of finite state machine for normalizing. IA filename converter maps an old filename to a new filename. A converter H takes a typed file representing a directory name or a filename without L extension, and only needs to determine the new name based on the old name. K It does not need to worry about extracting the file path from an absolute I path or determining the file extension, as all functions in this module G that use a FilenameConverter will only pass in typed files containing G the last directory (if a directory) or the filename without extension  if a file. ?Represents a filepath together with the type of file to which  the path refers. ARepresents the result of a rename attempt, which either fails or B succeeds. In both cases, the typed file path is that of the file ? for which a rename attempt was made. Upon failure, the string B parameter contains information about the error (may have been an C os-level error or user error); upon success, the string parameter D is the name to which the file was renamed (which includes the case E that no change was performed because old and new names were equal). BRepresents the type of a file or directory. These are exhaustive, @ as for purposes of this module, we consider everything that isn't  a directory to be a file. IRename a single file or directory using the supplied filename converter, B which will be passed just the directory name (without any parent E directories or a terminal slash) in the case of a directory or just D the filename without the extension in the case of a file. If there G already exists a file with the intended new name, nothing is done. If L the new name is the same as the old name (not considering file extension), I then the function successfully returns without touching the filesystem. G In all cases where a file is renamed, the extension of a file will be @ automatically converted to lowercase but otherwise remains the ; same (no characters are ever removed from the extension). =Renames the old file or directory to the new path, returning < a result that indicates success or failure. If successful, C the name of the new file is the success message; if unsuccessful, - the failure message gives more information. GRename all files and directories, recursively, in the given directory, I using the supplied filename converter to determine the new name of each H file or directory. The converter function will be called once for each H file or directory, and will be passed just the directory name (without I the parent directories) in the case of a directory or just the filename J without the extension in the case of a file. The extension of files (but I not directories if they seem to have an extension) will be converted to J lower case, but is not otherwise changed. There will be one RenameResult J for each success or failure, and an indication of the reason for failure 3 for failures, or the new name in case of success. 9Determine if the filename does not represent a dot file (. or ..). HDetermine whether there exists a file or directory with the given path. HGenerate a list of all files and directories below the given directory, F in depth-first order such that all files in a given directory appear 8 before the directory or any of its parent directories. EGet a list of files and directories, as TypedFilePath, for the given 2 directory, with directories sorted before files. 8Converts a list of lists and a list into a single list, 8 ensuring that all items of the single list are *after* ) all items from the list of lists. E.g.,  prepend [[1,2], [3,4], [5,6,7]] [66,67] == [1,2,3,4,5,6,7,66,67] 3Determine whether the given FileType is Directory. =Convert a filepath to a TypedFilePath. A Directory is a file B for which Directory.doesDirectoryExist returns true. If the path D does not represent a directory, it is considered a file, and there E is no further testing to verify that a file with that path actually  exists. ESort the paths in a given directory by putting all directories first G and then sorting by path within each type. It is designed for sorting E all files and directories in the top level of a directory, and will @ probably not provide a useful ordering if full paths are used. =Compare two typed file paths, using the built-in ordering of & FileType (dir before file) and path. >Normalize the filename of the given typed file path using the ? supplied FilenameConverter function, which will be passed the D directory name (without parent directories) in case of a directory C or the filename (without any parent directories or the extension) D in case of a file. This function takes care of extracting the part A of the path that is to be normalized, calling the user-supplied 9 function with only that part, and then reassembling the : result of the filename converter into a full path again. ?The default filename converter, which normalizes a filename by H converting letters to lowercase and converting one or more undesirable C characters into a single hyphen (or removing altogether if at the F beginning or the end of the name). The only exception to these rules 6 is that an initial dot of a filename is not removed. =The transition function of the fsm. The transition rules are > very simple: if we see a normal character, we always emit it C and transition to normal state. If we see a non-normal character, = we never emit it, and we stay in initial state if currently 7 in initial state, or else transition to hyphen state.  The normalize'+ function above takes care of emitting the 2 hyphen when we transition from hyphen to normal. >Split path into directory part (without slash) and file part. +Split file path into filename and ext. If           !"denominate-0.4.2System.DenominateFilenameConverter TypedFilePath RenameResultSuccessFailureFileTypeFile Directoryrename renameAll allFilepathsfileToTypedFilePathnormalizeFilenamedefaultFilenameConverterState NormalBlock HyphenBlockInitial doRenameSafe isNotDotFile fileExistsgetFilesAndDirectoriesprependisDirectoryFileType sortPathscompareTypedFilePathsconvert' transition joinFileName joinFileExt dirAndFile fileAndExt