Nimster has asked for the wisdom of the Perl Monks concerning the following question:

Hey,

what I'm trying to do is get the start of an HTML file (until it meets ) insert the contents of form.txt, and print the rest of of the html file (from to the end).

Via debugging, I've made sure that I do indeed get the line numbers right with the first part.

The current output gives me the end of the file (after the , and after it, the form.txt content. I just don't understand what's wrong in such small a program.

#!E:/perl/bin/perl use CGI qw(:all); use strict; print header; my ($startline, $endline); open (TEMPLATE, "index.shtml") || die "cannot find index.shtml: $!"; while (<TEMPLATE>) { $startline = $. if /^\s*<!-- MAIN -->.*$/; $endline = $., last if /^\s*<!-- ENDMAIN -->.*$/; } $startline--; $endline--; my @index=<TEMPLATE>; for (0..$startline) { print $index[$_]; } open (FORMTEMPLATE, 'form.txt') || die "cannot find form.txt: $!"; while (<FORMTEMPLATE>) { print; } for ($endline..$index[-1]) { print $index[$_]; }


-Nimster

Replies are listed 'Best First'.
Re: Mixed-up output
by chipmunk (Parson) on Jan 16, 2001 at 01:21 UTC
    It looks like you forgot to seek back to the beginning of the file before you read into @index. As is, @index only holds the lines after <!-- ENDMAIN -->, so when you think you're printing the start of the file you're actually printing the end.

    This isn't the best way to write the program, though. Instead of reading in the entire template, then printing out the pieces, it's simpler to loop for each section, and exit a loop when the next section starts:

    #!E:/perl/bin/perl use CGI qw(:all); use strict; print header; open (TEMPLATE, "index.shtml") || die "cannot find index.shtml: $!"; while (<TEMPLATE>) { print; last if /^\s*<!-- MAIN -->.*$/; } while (<TEMPLATE>) { print, last if /^\s*<!-- ENDMAIN -->.*$/; } open (FORMTEMPLATE, 'form.txt') || die "cannot find form.txt: $!"; while (<FORMTEMPLATE>) { print; } while (<TEMPLATE>) { print; }
      OMG, Chipmunk, ovid, eg, you're all right... :~(
      I can't believe I was sitting on that silly thing for 4 hours without noticing. However, chipmunk, can you explain your solution? I see how you integrated my code better inside itself so it won't run over the same thing twice - but what you did is:
      Print template up until <!-- MAIN --> Print template from <!-- ENDMAIN --> to end. Print the contents of form.txt then print template again?
      and it will appear in that order? Am I missing something, or did you just misunderstand my initial intention of placing one within the other?

      -Nimster
        I think the second step is the one that's not clear. Here's how my solution works:
        Read and print from TEMPLATE until <!-- MAIN -->. Read but don't print from TEMPLATE until <!-- ENDMAIN -->. Read and print everything from FORMTEMPLATE. Read and print everything that's left from TEMPLATE.
        I figured that <!-- MAIN --> and <!-- ENDMAIN --> may contain some text that should be replaced by the form. The second loop just skips over all of that.
      Speaks for itself, isn't perfect tho.
      my $printed; while (<TEMPLATE>) { if (/<!-- MAIN -->/ .. /<!-- ENDMAIN -->/) { unless ($printed) { open FORMTEMPLATE, 'form.txt' or die "cannot find form.txt: $!"; local $_; print while (<FORMTEMPLATE>) close FORMTEMPLATE; $printed++; } } else { print; } }
(Ovid) Re: Mixed-up output
by Ovid (Cardinal) on Jan 16, 2001 at 01:25 UTC
    The problem is that you never reset the read position on the file before you do my @index=<TEMPLATE>. That line reads from TEMPLATE everything after the last read. Try using seek.
    seek (TEMPLATE, 0, 0); # reposition to start of file my @index=<TEMPLATE>;
    As a side note (and possibly to start some interesting discussion), this is one instance where I don't necessarily think using CGI.pm is appropriate. Since you are not using any of the CGI functions except for header(), this is a lot of overhead.

    Instead of:

    print header;
    Perhaps this:
    print "Content-Type: text/html\n\n";
    Of course, if this is just a small subset of your code and you use other functions of CGI.pm, then this is a moot point. Just thought I'd toss that out there...

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Mixed-up output
by lemming (Priest) on Jan 16, 2001 at 01:22 UTC
    You read the file until endline in the first while loop
    You then read the rest of the file into @index and $startline is probably greater than the tail of the file, so you print it.
    You then print your template and then print whatever is left in @index which is empty.
Re: Mixed-up output
by eg (Friar) on Jan 16, 2001 at 01:24 UTC

    You need to seek back to the beginning of your file before reading it the second time.