my %is_approved_element = map { $_ => 1 } qw(a b big blockquote br center cite
code dd div dl dt em font hr i img
i ol p pre samp small span strong
sub sup table td th tr tt u ul);
my %is_block_element = map { $_ => 1 } qw(blockquote center div dl ol pre table ul);
my %is_raw_element = map { $_ => 1 } qw(dl ol pre table ul);
my %is_empty_element = map { $_ => 1} qw(br img hr);
sub render_text {
my $str = shift;
my $no_margin = shift;
my $buf;
my @tag_stack;
my $raw;
my $nl;
my $in_p;
$str =~ s/&(?!\#?[a-zA-Z0-9]+;)/&/g;
$str =~ s{
tag produced by \n\n should go after a
tag, # not before it. $need_p = 0; if ($close && $in_p) { $buf .= ''; $in_p = 0; } if ($is_raw_element{$name}) { if ($close) { $raw--; } else { $raw++; } } } if ($close) { # Catch a pending \n so it doesn't get translated to
. if ($nl) { $out .= "\n"; $nl = 0; } if ($tag_stack[0] eq $name) { $out .= "$name>"; shift(@tag_stack); } } else { $out .= "<$name$attributes>"; unless ($is_empty_element{$name}) { unshift(@tag_stack, $name); $str =~ s/^(\n+)//; $out .= $1; } } } else { $out = "<$close$name$attributes>"; } } else { $out = '<'; } } elsif ($str =~ s/^>//) { $out = '>'; } elsif ($str =~ s/^(\n{2,})//) { if ($in_p) { $buf .= ''; $in_p = 0; } $buf .= $1; } elsif ($str =~ s/^\n//) { if ($raw) { $buf .= "\n"; } else { $nl = 1; } } if ($out) { if ($nl) { $buf .= "
\n"; $nl = 0; } if ($need_p) { $buf .= ''; $in_p = 1; } $buf .= $out; } } for my $name (@tag_stack) { $buf .= "$name>"; } if ($in_p) { $buf .= '
'; } if ($no_margin) { my $first_p = index($buf, ''); my $last_p = rindex($buf, '
'); if ($first_p == $last_p) { substr($buf, $first_p + 2, 0) = q| style="margin: 0"|; } else { if ($last_p >= 0) { substr($buf, $last_p + 2, 0) = q| style="margin-bottom: 0"|; } if ($first_p >= 0) { substr($buf, $first_p + 2, 0) = q| style="margin-top: 0"|; } } } return $buf; }