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',
version => '2013.0426',
},
{
package => 'Text-TabularDisplay',
module => 'Text::TabularDisplay',
feature => 'Table formatting inside bug comments',
},
{
package => 'LWP-MediaTypes',
module => 'LWP::MediaTypes',

View File

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

View File

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