Format tables as HTML, not as ASCII pseudographic

beta
Vitaliy Filippov 2018-05-21 14:27:09 +03:00
parent 3e36282959
commit d34758d028
5 changed files with 25 additions and 150 deletions

View File

@ -130,11 +130,6 @@ sub REQUIRED_MODULES {
module => 'Text::Wrap', module => 'Text::Wrap',
version => '2013.0426', version => '2013.0426',
}, },
{
package => 'Text-TabularDisplay',
module => 'Text::TabularDisplay',
feature => 'Table formatting inside bug comments',
},
{ {
package => 'LWP-MediaTypes', package => 'LWP-MediaTypes',
module => 'LWP::MediaTypes', module => 'LWP::MediaTypes',

View File

@ -171,13 +171,17 @@ sub makeTables
{ {
if (scalar($line =~ s/(\t+|│+)/$1/gso) > 0) if (scalar($line =~ s/(\t+|│+)/$1/gso) > 0)
{ {
$line =~ s/^\s*│\s*//; $line =~ /[─┌┐└┘├┴┬┤┼]+/gso; # legacy ascii tables
$table->add(split /\t+|\s*│+\s*/, $line); $line =~ s/^\s*│\s*//s;
$line =~ s/\s*│\s*$//s;
$line = [ split /\t+\s*|\s*│+\s*/, $line ];
$line = '<tr><td>'.join('</td><td>', @$line).'</td></tr>';
$table .= "\n".$line;
next; next;
} }
else else
{ {
$wrappedcomment .= "\0\1".$table->render."\0\1"; $wrappedcomment .= "<table class='bz_fmt_table'>$table</table>\n";
$table = undef; $table = undef;
} }
} }
@ -185,21 +189,19 @@ sub makeTables
if ($n > 1 && length($line) < MAX_TABLE_COLS) if ($n > 1 && length($line) < MAX_TABLE_COLS)
{ {
# Table # Table
$line =~ s/^\s*│\s*//; $line =~ /[─┌┐└┘├┴┬┤┼]+/gso; # legacy ascii tables
$line =~ s/\s*│\s*$//; $line =~ s/^\s*│\s*//s;
$table = Text::TabularDisplay::Utf8->new; $line =~ s/\s*│\s*$//s;
$table->add(split /\t+|\s*│+\s*/, $line); $line = [ split /\t+\s*|\s*│+\s*/, $line ];
$table = "<tr><td>".join('</td><td>', @$line)."</td></tr>\n";
next; next;
} }
unless ($line =~ /^[│─┌┐└┘├┴┬┤┼].*[│─┌┐└┘├┴┬┤┼]$/iso) $line =~ s/\t/ /gso;
{
$line =~ s/\t/ /gso;
}
$wrappedcomment .= $line . "\n"; $wrappedcomment .= $line . "\n";
} }
if ($table) if ($table)
{ {
$wrappedcomment .= "\0\1".$table->render."\0\1"; $wrappedcomment .= "<table class='bz_fmt_table'>$table</table>\n";
} }
return $wrappedcomment; return $wrappedcomment;
} }
@ -215,8 +217,6 @@ sub quoteUrls
my ($text, $bug, $comment) = (@_); my ($text, $bug, $comment) = (@_);
return $text unless $text; return $text unless $text;
$text = makeTables($text);
# We use /g for speed, but uris can have other things inside them # We use /g for speed, but uris can have other things inside them
# (http://foo/bug#3 for example). Filtering that out filters valid # (http://foo/bug#3 for example). Filtering that out filters valid
# bug refs out, so we have to do replacements. # bug refs out, so we have to do replacements.
@ -345,6 +345,9 @@ sub quoteUrls
# Replace nowrap markers (\1\0\1) # Replace nowrap markers (\1\0\1)
$text =~ s/\x01\x00\x01(.*?)\x01\x00\x01/<div style="white-space: nowrap">$1<\/div>/gso; $text =~ s/\x01\x00\x01(.*?)\x01\x00\x01/<div style="white-space: nowrap">$1<\/div>/gso;
# Replace tables
$text = makeTables($text);
# Color quoted text # Color quoted text
$text = makeCitations($text); $text = makeCitations($text);

View File

@ -60,7 +60,6 @@ use List::Util qw(first);
use Scalar::Util qw(tainted blessed); use Scalar::Util qw(tainted blessed);
use Template::Filters; use Template::Filters;
use Text::Wrap; use Text::Wrap;
use Text::TabularDisplay::Utf8;
use JSON; use JSON;
use Data::Dumper qw(Dumper); use Data::Dumper qw(Dumper);
@ -457,17 +456,18 @@ sub wrap_comment # makeParagraphs
my $tmp; my $tmp;
my $text = ''; my $text = '';
my $block_tags = '(?:div|h[1-6]|center|ol|ul|li)'; my $block_tags = '(?:div|h[1-6]|center|ol|ul|li)';
my $table_tags = '(?:table|tbody|thead|tr|td|th)';
while ($input ne '') while ($input ne '')
{ {
# Convert double line breaks to new paragraphs # Convert double line breaks to new paragraphs
if ($input =~ m!\n\s*\n|(</?$block_tags[^<>]*>)!so) if ($input =~ m!\n\s*\n|(</?$table_tags[^<>]*>)|(</?$block_tags[^<>]*>)!so)
{ {
@m = (substr($input, 0, $-[0]), $1); @m = (substr($input, 0, $-[0]), $1||$2, $1);
$input = substr($input, $+[0]); $input = substr($input, $+[0]);
} }
else else
{ {
@m = ($input, ''); @m = ($input, '', '');
$input = ''; $input = '';
} }
if ($m[0] ne '') if ($m[0] ne '')
@ -476,7 +476,7 @@ sub wrap_comment # makeParagraphs
$m[0] =~ s/^\s*\n//s; $m[0] =~ s/^\s*\n//s;
$m[0] =~ s/^([ \t]+)/$tmp = $1; s!\t! !g; $tmp/emog; $m[0] =~ s/^([ \t]+)/$tmp = $1; s!\t! !g; $tmp/emog;
$m[0] =~ s/(<[^<>]*>)|( +)/$1 || ' '.('&nbsp;' x (length($2)-1))/ge; $m[0] =~ s/(<[^<>]*>)|( +)/$1 || ' '.('&nbsp;' x (length($2)-1))/ge;
if (!$p && $m[0] ne '') if (!$p && $m[0] ne '' && !$m[2])
{ {
$text .= '<p>'; $text .= '<p>';
$p = 1; $p = 1;

View File

@ -1,126 +0,0 @@
package Text::TabularDisplay::Utf8;
use utf8;
use strict;
use base 'Text::TabularDisplay';
# -------------------------------------------------------------------
# render([$start, $end])
#
# Returns the data formatted as a table. By default, all rows are
# returned; if $start or $end are specified, then only those indexes
# are returned. Those are the start and end indexes!
# -------------------------------------------------------------------
sub render {
my $self = shift;
my $start = shift || 0;
my $end = shift || $#{ $self->{ _DATA } };
my $size = $self->{ _SIZE };
my (@columns, $datum, @text);
push @text, '┌' . join("┬", map( { "─" x ($_ + 2) } @{ $self->{ _LENGTHS } })) . '┐';
if (@columns = $self->columns) {
push @text, _format_line(\@columns, $self->{ _LENGTHS });
push @text, '├' . join("┼", map( { "─" x ($_ + 2) } @{ $self->{ _LENGTHS } })) . '┤';
}
for (my $i = $start; $i <= $end; $i++) {
$datum = $self->{ _DATA }->[$i];
last unless defined $datum;
# Pad the array if there are more elements in @columns
push @$datum, ""
until (@$datum == $size);
push @text, _format_line($datum, $self->{ _LENGTHS });
}
push @text, '└' . join("┴", map( { "─" x ($_ + 2) } @{ $self->{ _LENGTHS } })) . '┘';
return join "\n", @text;
}
# -------------------------------------------------------------------
# _column_length($str)
# -------------------------------------------------------------------
sub _column_length
{
my ($str) = @_;
my $len = 0;
for (split "\n", $str) {
$len = length
if $len < length;
}
# why the /hell/ this length is tainted?..
if (${^TAINT})
{
($len) = $len =~ /(\d+)/so;
}
return $len;
}
undef &Text::TabularDisplay::_column_length;
*Text::TabularDisplay::_column_length = \&_column_length;
# -------------------------------------------------------------------
# _format_line(\@columns, \@lengths)
#
# Returns a formatted line out of @columns; the size of $column[$i]
# is determined by $length[$i].
# -------------------------------------------------------------------
sub _format_line {
my ($columns, $lengths) = @_;
my $height = 0;
my @col_lines;
for (@$columns) {
my @lines = split "\n";
$height = scalar @lines
if $height < @lines;
push @col_lines, \@lines;
}
my @lines;
for my $h (0 .. $height - 1 ) {
my @line;
for (my $i = 0; $i <= $#$columns; $i++) {
my $val = defined($col_lines[$i][$h]) ? $col_lines[$i][$h] : '';
push @line, sprintf " %-" . $lengths->[$i] . "s ", $val;
}
push @lines, join '│', "", @line, "";
}
return join "\n", @lines;
}
1;
__END__
=head1 NAME
Text::TabularDisplay::Utf8 - Display text in formatted table output using UTF-8 pseudographics
=head1 SYNOPSIS
use Text::TabularDisplay::Utf8;
my $table = Text::TabularDisplay::Utf8->new(@columns);
$table->add(@row)
while (@row = $sth->fetchrow);
print $table->render;
id name
1 Tom
2 Dick
3 Barry
(aka Bazza)
4 Harry
=head1 DESCRIPTION
The program interface is fully compatible with C<Text::TabularDisplay> -
see its perldoc for more information.

View File

@ -26,6 +26,9 @@
.bz_comment .attachment_image { max-width: 50em; margin: 10px 0px 0px 0px; } .bz_comment .attachment_image { max-width: 50em; margin: 10px 0px 0px 0px; }
.bz_comment_text.bz_fullscreen_comment { min-width: 50em; width: 100%; word-wrap: break-word; } .bz_comment_text.bz_fullscreen_comment { min-width: 50em; width: 100%; word-wrap: break-word; }
#commentpreviewhtml .bz_comment_text.bz_fullscreen_comment { min-width: 40em; }
.bz_comment .bz_fmt_table td, .bz_comment .bz_fmt_table th { border: 1px solid gray; padding: 5px; }
#comments > table, .bz_section_additional_comments > table { table-layout: fixed; } #comments > table, .bz_section_additional_comments > table { table-layout: fixed; }