in reply to Re: Group __DATA__ lines in a while? in thread Group __DATA__ lines in a while?
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
Re^3: Group __DATA__ lines in a while?
by hdb (Monsignor) on Oct 21, 2013 at 07:01 UTC
|
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, [ \¶graph, $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. | [reply] [d/l] [select] |
|
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
| [reply] [d/l] |
|
section($tab, sub {
for my $line (@$_) {
heading($tab,$1,$2, { id => idify($2) }), next if $line =~ /^(
+[1-6])\s+(.*)/;
line($tab,$line), next if $line =~ /^<
+/;
line($tab,"<$line>"), next if $line =~ /^[
+bh]r$/;
paragraph($tab,$line);
}
}) for @sections;
I like this for its tabular look where the action is on the left and the condition on the right. It also avoids the chain of elsifs. The danger is that it becomes difficult to stay the course when the actions become more complex...
| [reply] [d/l] [select] |
|
|
|
|
|
|