How Can Create An Html Document From Several Files In Perl?
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/perluse strict; # never forget this lineuse warnings; # or this one, it's better than the -w flaguse CGI qw(:standard); # this gives us convenient functions for outputting# HTML, plus other stuff for processing CGI requestsmy @filelist = ( 'file1', 'file2', 'file3' );
print header;
print start_html;
print start_table;
foreachmy $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:
foreachmy $file( @filelist ) {
openmy $fh, $file ordie"Could not open $file: $!";
local $/ = undef; # this allows us to slurp the whole file at oncemy $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/perluse strict; use warnings;
use autodie;
use HTML::Template;
my @files = qw(file1 file2);
my @files_loop;
formy $file (@files) {
openmy $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 usestrict; # Always, until you know when to turn it off--and then in a limited scope.usewarnings; # 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 foreachforeach my $file ( @filelist ) {
# do you really want a new table for each file?print"<table>\n";
# need to escape your quotesprint"<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 contentsprint"<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 {
formy $file (@filelist) {
openmy $fh, '<', $file ornext;
row {
formy $title (<$fh>) {
chomp $title;
cell { $file }
cell ( class => title_class( $title ), title => $title ) {}
} } } } } } };
print CGI::header();
print main->render( 'web' );
subtitle_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/perluse strict; # never forget this lineuse warnings; # or this one, it's better than the -w flaguse CGI qw(:standard); # this gives us convenient functions for outputting# HTML, plus other stuff for processing CGI requestsmy @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";
foreachmy $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?"