Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Group __DATA__ lines in a while?

by hdb (Monsignor)
on Oct 21, 2013 at 05:53 UTC ( [id://1059067]=note: print w/replies, xml ) Need Help??


in reply to Group __DATA__ lines in a while?

Not quite sure what you are looking for as your code seems to be doing what you want. As per your table of contents, you could push each $line (or [ $heading, $text ]) onto some array @toc whenever you encounter a heading and format it when you are through with all the data.

Replies are listed 'Best First'.
Re^2: Group __DATA__ lines in a while?
by Lady_Aleena (Priest) on Oct 21, 2013 at 06:12 UTC

    I would like to wrap each section in an HTML <section>. Also, the subroutines (line, heading, and paragraph) used in story print immediately. It appears to get the table of contents, I will have to go through the lines twice.

    sub story { my ($source,$author) = @_; my $tab = 3; my @toc; while (my $line = <$source>) { chomp($line); if ($line =~ /^2/) { my ($number,$text) = split(/ /,$line,2); push @toc, anchor($text, { href => '#'.idify($text) }); } } list($tab, 'u', \@toc, { class => 'two' }); # I ran $source above, so I can't have it here! /me head desks. while (my $line = <$source>) { chomp($line); # If a line starts with a bracket, just print the line. if ($line =~ m/^</) { line($tab,$line); } # If a line starts with a numeral 1-6, print a heading. elsif ($line =~ /^[1-6]\s/) { my ($heading,$text) = split(/ /,$line,2); my $id = idify($text); heading($tab,$heading,$text, { id => $id }); } # If a line is a break or horizontal rule, print the line in brack +ets. elsif ($line =~ /^[bh]r$/) { line($tab,"<$line>"); } # All other lines are paragraphs. else { paragraph($tab,$line); } } # If I wrote a story, I want people to know I wrote it at the bottom +. paragraph($tab,"written by $root_user", { class => 'author' }) if !$ +author; }
    No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
    Lady Aleena

      How about delayed execution? You push all commands onto a stack and only execute after reading all data:

      sub story { my ($source,$author) = @_; my $tab = 3; my @toc; my @commands; push @commands, [ \&startsection, "Lead" ]; # I ran $source above, so I can't have it here! /me head desks. while (my $line = <$source>) { chomp($line); # If a line starts with a bracket, just print the line. if ($line =~ m/^</) { push @commands, [ \&line, $tab, $line ]; } # If a line starts with a numeral 1-6, print a heading. elsif ($line =~ /^[1-6]\s/) { my ($heading,$text) = split(/ /,$line,2); if( $heading == 2 ) { push @toc, anchor($text, { href => '#'.idify($text) } +); if( $commands[-1]->[0] eq \&startsection ) { # not sur +e this comparison is valid... pop @commands; # to avoid empty sections } else { push @commands, [ \&endsection ]; } push @commands, [ \&startsection, $text ]; # adapt arg +uments as required } my $id = idify($text); push @commands, [ \&heading, $tab,$heading,$text, { id => +$id } ]; } # If a line is a break or horizontal rule, print the line in b +rackets. elsif ($line =~ /^[bh]r$/) { push @commands, [ \&line, $tab, "<$line>" ]; } # All other lines are paragraphs. else { push @commands, [ \&paragraph, $tab, $line ]; } } push @commands, [ \&endsection ]; # do the table of contents list($tab, 'u', \@toc, { class => 'two' }); # delayed execution of all print commands for (@commands) { my $cmd = shift @$_; $cmd->(@$_); } # If I wrote a story, I want people to know I wrote it at the bott +om. paragraph($tab,"written by $root_user", { class => 'author' }) if +!$author; }

      I cannot test this code but it hopefully conveys the idea...

      startsection and endsection would be two subs to print the HTML to start and end a section.

      Update: some changes in formatting of the post and added a missing comma in the code.

      Update: added a missing endsection at the end.

        I think I got it, however, I didn't use your code. I'm sorry. Here is how I did it.

        sub story { my ($source,$author) = @_; my $tab = 3; my $inc = 0; my @sections; my @toc; while (my $line = <$source>) { chomp($line); if ($line =~ /^2/) { $inc++; my ($number,$text) = split(/ /,$line,2); push @toc, anchor($text, { href => '#'.idify($text) }); } push @{$sections[$inc]}, $line; } list($tab, 'u', \@toc, { class => 'two' }) if @toc > 3; for my $section (@sections) { section($tab, sub { for my $line (@{$section}) { chomp($line); if ($line =~ m/^</) { line($tab,$line); } elsif ($line =~ /^[1-6]\s/) { my ($heading,$text) = split(/ /,$line,2); my $id = idify($text); heading($tab,$heading,$text, { id => $id }); } elsif ($line =~ /^[bh]r$/) { line($tab,"<$line>"); } else { paragraph($tab,$line); } } }); } paragraph($tab,"written by $root_user", { class => 'author' }) if !$ +author; }
        No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
        Lady Aleena

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1059067]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (5)
As of 2024-04-16 12:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found