in reply to Re^8: Directory Tree Structure
in thread Directory Tree Structure

When you say "got rid of the warning, but didn't fix the problem", do you mean that you are still seeing "empty" lines in the output? I'm not seeing that when I run the version below (sanitized to make it non-dependent on your specific paths).

I added the minimal amount of stuff around the "print_tree()" function so that I could load it in a browser and even paste it into this validation tool that almut cited elsewhere in this thread; I see no blank lines in the raw or rendered html, and it passed validation (with just a couple warnings about unrelated stuff).

If you're still seeing a problem with your directory tree, maybe there's something strange in the file names that you are dealing with (e.g. html-reserved characters in a file name, or something like that). In that case, it'll be worthwhile to get a plain-text dump of the tree to see if that's the problem -- or better yet, add HTML::Entities to your program, and use its "encode_entities" method on all the file names.

In fact, I've gone ahead and done that in the version below, just because it's a good idea anyway.

#!/usr/bin/perl use strict; use warnings; use diagnostics; use Cwd; use File::Find; use File::Basename; use HTML::Entities; my $filename = basename($0); my $rootdir = getcwd; my %tree; $tree{$rootdir} = {}; find( { wanted => \&wanted }, $rootdir ); print "<html><head><title>Testing</title></head><body>\n"; print_tree( \%tree, 0 ); print "</body></html>\n"; sub wanted { local $_ = $File::Find::name; if ( -f ) { # only work on data files (skip directories) s{\Q$rootdir\E/}{}; # remove the rootdir string from the path name load_tree( $tree{$rootdir}, fileparse( $_ )); } } # recursively load the hash structure # (first call gets top-level hashref, and file name, path from File::B +asename::fileparse) sub load_tree { my ( $href, $name, $path ) = @_; my @dirs = split /\//, $path; push @dirs, '.' if ( $dirs[$#dirs] ne '.' ); my $key = shift @dirs; while ( @dirs and $key ne '.' and exists( $$href{"$key/"} )) { $href = $$href{"$key/"}; $key = shift @dirs; } if ( $key ne '.' and ! exists( $$href{"$key/"} )) { $$href{"$key/"} = {}; load_tree( $$href{"$key/"}, $name, join( '/', @dirs, '' )); } elsif ( $key eq '.' ) { push @{$$href{"$key/"}}, $name; } } # recursively print embedded lists sub print_tree { my ( $href, $indent ) = @_; printf( "%s<ul>\n", ' ' x $indent ); $indent++; if ( exists( $$href{'./'} )) { printf( "%s<li>%s</li>\n", ' ' x $indent, encode_entities( $_ )) for ( @{$$href{'./'}} ); delete $$href{'./'}; } if ( keys %$href ) { for my $subdir ( sort keys %$href ) { printf( "%s<li>%s\n", ' ' x $indent, encode_entities( $subdir +)); $indent++; print_tree( $$href{$subdir}, $indent ); $indent--; printf( "%s</li>\n", ' ' x $indent ); } } $indent--; printf( "%s</ul>\n", ' ' x $indent ); }
(updated to fix validation web site link)

Replies are listed 'Best First'.
Re^10: Directory Tree Structure
by Lady_Aleena (Priest) on Nov 05, 2009 at 19:59 UTC
    I think I have figured out why the above works wonky for me. The root directory on my home computer has my name in it. The period after my middle initial is messing up sub load_tree. So, can we change the dots to something else?
    Have a nice day!
    Lady Aleena
      I'm not really convinced about your diagnosis. If you have a directory name like "Firstname I. Lastname", that whole string should be showing up (with spaces and period character) as one of the the hash keys when you split the path on slash characters. There might be something else screwy in your directory structure or file names. (Have you ever seen a line-feed and/or carriage-return character used as (part of) a file name? I have. It does nasty things.)

      You can go ahead and try something besides "." for the parts in the code that use "." (or "./") as a hash key. Or, you could try renaming the directory that has your middle initial in its name, to see if that makes the problem go away. Or you could create a symbolic link ("shortcut" in windows parlance) to that directory so that you can use some other string as its path name.

      In any case, I don't think there's anything more I can do here. It works for me, and I can't replicate the problem you're having. (Does it work for you on other paths, at least?)