Skip to content Skip to sidebar Skip to footer

How Can Create An HTML Document From Several Files In Perl?

I need some help making this script... so far I think it should look something like this (I tend to use AWK a lot) #!/usr/bin/perl -w @filelist=( file1, file2, file3 ) print ('<

Solution 1:

Your code doesn't really make any sense. I suggest taking a look at a basic Perl intro before trying anything more complicated.

That said, what you're probably trying to do is something like this:

#!/usr/bin/perl

use strict;      # never forget this line
use warnings;    # or this one, it's better than the -w flag

use CGI qw(:standard);   # this gives us convenient functions for outputting
                         # HTML, plus other stuff for processing CGI requests

my @filelist = ( 'file1', 'file2', 'file3' );

print header;
print start_html;
print start_table;

foreach my $file( @filelist ) { 
    print Tr( td( $file ) );
}

print end_table;
print end_html;

For the (extensive) documentation for the CGI module, see CGI at CPAN.

Edit

If you want the content of each file in the table, then you'll need to read each file into a variable inside the loop. Here's an example of how you could do it:

foreach my $file( @filelist ) { 
    open my $fh, $file or die "Could not open $file: $!";

    local $/ = undef;   # this allows us to slurp the whole file at once
    my $filedata = <$fh>;

    print Tr( td( $filedata ) );
}

Some more docs that you should read: Perl open() tutorial, and all about slurping.


Solution 2:

Use HTML::Template so that you have full control over the HTML and your code is not unreadable. See my answer to another question for an example of how to embed the template in your code. Of course, the same template can exist outside of the script and that's the benefit of separating presentation from logic.

#!/usr/bin/perl

use strict; use warnings;
use autodie;

use HTML::Template;

my @files = qw(file1 file2);
my @files_loop;

for my $file (@files) {
    open my $fh, '<', $file;

    push @files_loop, {
        LINES => [
            map { chomp; length $_ ? {LINE => $_} : () } <$fh>
    ]};
}

my $tmpl = HTML::Template->new(filehandle => \*DATA);
$tmpl->param(FILES => \@files_loop );
print $tmpl->output;

__DATA__
<html>
<body>
<TMPL_LOOP FILES>
<table>
<TMPL_LOOP LINES><tr><td><TMPL_VAR LINE></td></tr></TMPL_LOOP>
</table>
</TMPL_LOOP>
</html>

Output:

C:\Temp> fish.pl
<html>
<body>

<table>
<tr><td>bye bye</td></tr><tr><td>hello</td></tr><tr><td>thank you</td></tr><tr><
td>no translation</td></tr>
</table>

<table>
<tr><td>chao</td></tr><tr><td>hola</td></tr><tr><td>gracias</td></tr>
</table>

</html>

Solution 3:

Run your code and read the error messages. You have multiple syntax errors.

Whatever tutorial you are reading does not give you some important advice:

#!/usr/bin/perl 

use strict;    # Always, until you know when to turn it off--and then in a limited scope.
use warnings;  # see perllexwarn for why this is better than -v  

# you need to quote those bare words.  qw is a handy quoting operator.  See perlop.
my @filelist = qw(  
    file1 
    file2
    file3
);             # added semicolon 

# use a heredoc for big chunks of text.
# your html is seriously bogus.  Fixed somewhat.
print <<'ENDHTML';
<html>
   <head>
   </head>
   <body>
ENDHTML

# $filelist does not exist.
# fixed syntax of foreach
foreach my $file ( @filelist ) {

  # do you really want a new table for each file?
  print "<table>\n";

  # need to escape your quotes
  print "<tr><td>\"$file\"</td></tr>";

  # open a file handle.
  # use lexical handles instead of old style global handles.
  # use 3 argument open instead of 2 argument style
  open( my $fh, '<', $file);

  # $fh evaluates to true if we were able to open the file.
  if ( $fh ) {

    # iterate over the file.
    while( my $line = <$fh> ) {
      # where the hell did $1 and $2 come from?
      print "<tr><td>$line</td></tr>";
    }

  }
  else {
      # put the error message in the table instead of the file contents
      print "<tr><td>Error opening file: $!</td></tr>";          
  }

  print "</table>";
}
print "</html>";

Since you didn't test your code, I didn't either. But it should work.

Of course inline HTML is best avoided in all but the most simple, throw-away scripts. If you are doing anything lasting or serious, use a templating system like Template::Toolkit or HTML::Template.


Solution 4:

Some excellent answers above. Here is yet another twist on the theme this time using Markapl based on Soop's answer.

use strict; 
use warnings;
use CGI ();
use Markapl;

my @filelist = qw/file1.txt file2.txt file3/;

template 'web' => sub {
  html {
    head {
      html_link (rel => 'stylesheet', type => 'text/css', href => 'test.css') {}
    }
    body {
      table {
        for my $file (@filelist) {
          open my $fh, '<', $file or next;
          row { 
            for my $title (<$fh>) { 
                chomp $title; 
                cell { $file }
                cell ( class => title_class( $title ), title => $title ) {}
} } } } } } };

print CGI::header();
print main->render( 'web' );

sub title_class {
    my $first_char = substr $_[0], 0, 1;
    return 'green' if $first_char >= 2;
    return 'amber' if $first_char == 1;
    return 'red';
}

I do like these "builder" type approaches. For some more see this SO question CL-WHO-like HTML templating for other languages?

/I3az/


Solution 5:

This is what I came up with from talking you guys - a big thanks to everyone :D

        #!/usr/bin/perl

    use strict;      # never forget this line
    use warnings;    # or this one, it's better than the -w flag

    use CGI qw(:standard);   # this gives us convenient functions for outputting
                             # HTML, plus other stuff for processing CGI requests

    my @filelist=(
'file1',
'file2',
'file3',
'file4',
'file5',
'file6',
    );
    #
    #
    print "<html>\n";
    print "<head>\n";
    print "<link rel=\"stylesheet\" type=\"text/css\" href=\"test.css\">\n";
    print "</head>\n";
    foreach my $file (@filelist) {
        print "<table>\n";
        print "<div>\n";
        print "<tr>\n";
        print  td( $file );
        open( my $fh, '<', $file);
        if ($fh) {
          while( my $line = <$fh> ) {
          chomp $line;
          if (substr($line, 0, 1)>="2") {
            print "<td class=\"green\" title=\"" . $line . "\">\n";
            }
          elsif (substr($line, 0, 1)=="1") {
            print ("<td class=\"amber\" title=\"" . $line . "\">\n");
            }
          elsif (substr($line, 0, 1)=="0") {
            print ("<td class=\"red\" title=\"" . $line . "\">\n");
            }
          }
        }
        print "</tr>\n";
        print "</div>\n";
        print "</table>\n";
    }
    print "</html>";

The HTML needs a little tweaking, and a lot of it is redundant, but it works fine :)


Post a Comment for "How Can Create An HTML Document From Several Files In Perl?"