
    if ($#ARGV != 0) {
        print("usage: perl crank.pl <project_name>\n");
        exit;
    }
    
    $proj = $ARGV[0];
    
    system("rm -rf NEW\n");
    system("mkdir NEW\n");
    system("cp -pr images NEW\n");

    $errs = 0;

    #   Phase 1: Walk through the files in the html
    #            subdirectory, find their topic tags, and
    #            create a map from the original idiot
    #            file names to names based on the tags.

    opendir(CD, "html");  
    @docs = grep(!/^\./, readdir(CD));
#    print @docs;
    @docs = sort(@docs);
    foreach $f (@docs) { 
#   print("$f\n");
        open(FI, "<html/$f") || die "Cannot open file html/$f";
        undef $topname;
        while ($s = <FI>) {
            if ($s =~ m/(<P><A NAME=")([^"]+)(")/) {
#   print(">>$1<< >>$2<<\n");
                $topname = $2;
                last;
            }
        }
        close(FI);
        if (!(defined $topname)) {
            print(STDERR "Unable to find topic in $f\n");
            $errs++;
        } else {
            $newname{$f} = $topname;
        }
    }
    if ($errs) {
        die "One or more topics could not be found in HTML files";
    }
    
    #   Phase 2: Make sure there are no duplicates among
    #            the topic names.  This would be disastrous.

    foreach $k (sort(keys(%newname))) {
        foreach $k1 (sort(keys(%newname))) {
            if (($k ne $k1) && ($newname{$k} eq $newname{$k1})) {
                print(STDERR "Files $k and $k1 both mapped into topic %newname{$k1}.\n");
                $errs++;
            }
        }
    }
    
    if ($errs) {
        die "One or more files contain the same topic name";
    }
    
    #   Phase 3: Walk through the list of files and copy
    #            each file to one named after the topic
    #            it contains.  At the same time, build
    #            a list of the new file names for subsequent
    #            use.
    
    system("rm -rf NEW/html\n");
    system("mkdir NEW/html\n");
    $nfiles = 0;
    foreach $k (sort(keys(%newname))) {
        $cmd = "cp html/$k NEW/html/$newname{$k}.htm\n";
#   print("CMD: $cmd");
        system($cmd);
        $files[$nfiles++] = "NEW/html/$newname{$k}.htm";
    }
    
    #   Phase 4: Patch references in the newly renamed
    #            files.
    
    for ($i = 0; $i < $nfiles; $i++) {
        patchFile($files[$i], $files[$i]);
    }

    #   Phase 5: Patch file names in the project definition
    #            and keyword files.
    
    patchFile("$proj.hhp", "NEW/$proj.hhp");
    patchFile("$proj.hhk", "NEW/$proj.hhk");

    #   Patch the references to old file names in a given
    #   file.
    
    sub patchFile {
        local ($ifile, $ofile) = @_;
        local (@txt, $i, $j, $k, $s, $nfn, $changes);
        
#   print("Patch $ifile to $ofile.\n");

        #   Read the file contents into memory

        $i = 0;
        open(TF, "<$ifile") || die "Cannot open file $ifile";
        while ($s = <TF>) {
            $txt[$i++] = $s;
        }
        close(TF);
        
        #   Patch the file contents
        
        $changes = 0;
        for ($j = 0; $j < $i; $j++) {
        
            #   Cosmetic patch topic title
            
            if ($txt[$j] =~ m/(<P><A NAME=")([^"]+)(")/) {
                $txt[$j] =~ s/P>/H3>/g;
            }
        
            #   Patch file name references
        
            foreach $k (sort(keys(%newname))) {
                if ($txt[$j] =~ m/$k/) {
                    $nfn = "$newname{$k}.htm";
                    $txt[$j] =~ s/$k/$nfn/g;
                    $changes++;
#   print("$k: $txt[$j]");
                }
            }
        }
        
        #   If any changes were made, write the modified
        #   text back to the output file.
        
        if ($changes) {
            open(TF, ">$ofile") || die "Cannot create updated file $ofile";
            for ($j = 0; $j < $i; $j++) {
                print(TF $txt[$j]);
            }
            close(TF);
#   print("Updating file $ofile\n");
        }
    }
