Skip Menu |

This queue is for tickets about the Text-Diff CPAN distribution.

Report information
The Basics
Id: 14468
Status: open
Priority: 0/
Queue: Text-Diff

People
Owner: Nobody in particular
Requestors: Marek.Rouchal [...] gmx.net
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 0.35
Fixed in: (no value)



Subject: Allow a max WIDTH for Table diffs
The attached patch implements a WIDTH option for Text::Diff::Table in order to limit the total table width to a given number of characters (e.g. the terminal width). Please feel free to review and/or adapt this patch according to your style, I'd be happy to see the feature in a new release of Text-Diff. Cheers, Marek
diff -ruN Text-Diff-0.35/MANIFEST Text-Diff-0.35p1/MANIFEST --- Text-Diff-0.35/MANIFEST 2002-07-14 14:52:16.000000000 +0200 +++ Text-Diff-0.35p1/MANIFEST 2005-09-05 09:31:56.813815000 +0200 @@ -10,3 +10,4 @@ t/keygen.t t/outputs.t t/table.t +t/table_w.t diff -ruN Text-Diff-0.35/lib/Text/Diff/Table.pm Text-Diff-0.35p1/lib/Text/Diff/Table.pm --- Text-Diff-0.35/lib/Text/Diff/Table.pm 2002-08-27 19:57:58.000000000 +0200 +++ Text-Diff-0.35p1/lib/Text/Diff/Table.pm 2005-09-05 09:45:49.753744000 +0200 @@ -2,13 +2,13 @@ =head1 NAME - Text::Diff::Table - Text::Diff plugin to generate "table" format output +Text::Diff::Table - Text::Diff plugin to generate "table" format output =head1 SYNOPSIS use Text::Diff; - diff \@a, $b { STYLE => "Table" }; + diff \@a, $b, { STYLE => "Table" }; =head1 DESCRIPTION @@ -71,7 +71,7 @@ @ISA = qw( Text::Diff::Base Exporter ); @EXPORT_OK = qw( expand_tabs ); -$VERSION = 1.2; +$VERSION = 1.3; use strict; use Carp; @@ -346,25 +346,94 @@ if defined $cols->[$i] && length $cols->[$i] > $w[$i]; } } + my $WIDTH = $options->{WIDTH}; - my %fmts = $four_column_mode - ? ( + my %fmts; + if($four_column_mode) { + if($WIDTH) { + # scale it - in 0 and 2 we have the numbers, 1 and 3 are the lines + # we need 10 chars for separators and whitespace + my $lw = $WIDTH - 7 - $w[0] -$w[2]; + my $ls = $w[1] + $w[3]; + $w[1] = int($w[1]*$lw/$ls); + $w[3] = int($w[3]*$lw/$ls); + %fmts = ( + "=" => "| %$w[0]s|%-$w[1]s| %$w[2]s|%-$w[3]s|\n", + "A" => "* %$w[0]s|%-$w[1]s* %$w[2]s|%-$w[3]s|\n", + "B" => "| %$w[0]s|%-$w[1]s* %$w[2]s|%-$w[3]s*\n", + "*" => "* %$w[0]s|%-$w[1]s* %$w[2]s|%-$w[3]s*\n", + ); + } else { + %fmts = ( "=" => "| %$w[0]s|%-$w[1]s | %$w[2]s|%-$w[3]s |\n", "A" => "* %$w[0]s|%-$w[1]s * %$w[2]s|%-$w[3]s |\n", "B" => "| %$w[0]s|%-$w[1]s * %$w[2]s|%-$w[3]s *\n", "*" => "* %$w[0]s|%-$w[1]s * %$w[2]s|%-$w[3]s *\n", - ) - : ( + ); + } + } else { # three-column mode + if($WIDTH) { + # scale it - in 0 we have the numbers, 1 and 2 are the lines + # we need 9 chars for separators and whitespace + my $lw = $WIDTH - 5 - $w[0]; + my $ls = $w[1] + $w[2]; + $w[1] = int($w[1]*$lw/$ls); + $w[2] = int($w[2]*$lw/$ls); + %fmts = ( + "=" => "| %$w[0]s|%-$w[1]s|%-$w[2]s|\n", + "A" => "* %$w[0]s|%-$w[1]s|%-$w[2]s|\n", + "B" => "| %$w[0]s|%-$w[1]s|%-$w[2]s*\n", + "*" => "* %$w[0]s|%-$w[1]s|%-$w[2]s*\n", + ); + } else { + %fmts = ( "=" => "| %$w[0]s|%-$w[1]s |%-$w[2]s |\n", "A" => "* %$w[0]s|%-$w[1]s |%-$w[2]s |\n", "B" => "| %$w[0]s|%-$w[1]s |%-$w[2]s *\n", "*" => "* %$w[0]s|%-$w[1]s |%-$w[2]s *\n", - ); + ); + } + } $fmts{bar} = sprintf $fmts{"="}, "", "", "", "" ; $fmts{bar} =~ s/\S/+/g; $fmts{bar} =~ s/ /-/g; - return join( "", + my $ret; + if($WIDTH) { + if($four_column_mode) { + $ret = join( "", + map { + sprintf( $fmts{$_->[-1]}, + $_->[0], + defined $_->[1] && length($_->[1]) > $w[1] ? substr($_->[1],0,$w[1]-1).">" : $_->[1], + $_->[2], + defined $_->[3] && length($_->[3]) > $w[3] ? substr($_->[3],0,$w[3]-1).">" : $_->[3] + ) + } ( + ["bar"], + @heading_lines, + @heading_lines ? ["bar"] : (), + @{$self->{ELTS}}, + ) + ); + } else { # three-column mode + $ret = join( "", + map { + sprintf( $fmts{$_->[-1]}, + $_->[0], + defined $_->[1] && length($_->[1]) > $w[1] ? substr($_->[1],0,$w[1]-1).">" : $_->[1], + defined $_->[2] && length($_->[2]) > $w[2] ? substr($_->[2],0,$w[2]-1).">" : $_->[2] + ) + } ( + ["bar"], + @heading_lines, + @heading_lines ? ["bar"] : (), + @{$self->{ELTS}}, + ) + ); + } + } else { # no WIDTH specified + $ret = join( "", map { sprintf( $fmts{$_->[-1]}, @$_ ) } ( @@ -373,11 +442,24 @@ @heading_lines ? ["bar"] : (), @{$self->{ELTS}}, ), - ); - + ); + } @{$self->{ELTS}} = []; + return $ret; } +=head1 OPTIONS + +The table diff allows to speficy a C<WIDTH> option: + + $d = diff($a, $b, { STYLE => 'Table', WIDTH => 80 }); + +The resulting table will not exceed the given width. Please note that +approx. 5 characters are required for the table layout, and another +2-6 for the line numbers. The line column widths are distributed +according to the ratio of the longest line in each column. If a line +is longer than the column width, the last character is C<E<gt>> to +indicate that the line continues. =head1 LIMITATIONS diff -ruN Text-Diff-0.35/t/general.t Text-Diff-0.35p1/t/general.t --- Text-Diff-0.35/t/general.t 2001-12-16 13:42:15.000000000 +0100 +++ Text-Diff-0.35p1/t/general.t 2005-09-05 08:21:58.442755000 +0200 @@ -126,8 +126,8 @@ warn "# diff options: $diff_opts\n" ; warn "# my options: $Diff_opts\n" ; ## Merge the outputs using A::D - my @E = split /^/g, $expect ; - my @G = split /^/g, $output ; + my @E = split /^/m, $expect ; + my @G = split /^/m, $output ; my $w = length "Expected" ; for ( @E, @G ) { s/\n/\\n/g ; diff -ruN Text-Diff-0.35/t/table_w.t Text-Diff-0.35p1/t/table_w.t --- Text-Diff-0.35/t/table_w.t 1970-01-01 01:00:00.000000000 +0100 +++ Text-Diff-0.35p1/t/table_w.t 2005-09-05 09:31:21.226898000 +0200 @@ -0,0 +1,101 @@ +#!/usr/local/bin/perl -w + +use strict ; +use Test ; +use Text::Diff ; + +sub t($$$$) { + my ( $a, $b, $wid, $exp ) = @_; + my $d = diff \$a, \$b, { STYLE => "Table", WIDTH => $wid }; + + ## Older Test.pms don't support ok( $foo, qr// ); + if($d eq $exp) { + ok(1); + } else { + warn "\nGot:\n$d\nExpected:\n$exp\n"; + ok(0); + } +} + +my $t1 = <<"EOT"; +This is +some text +that has a line which is quite longer than the other lines. +EOT +my $t2 = <<"EOT"; +This is +some text +that has another line which is quite longer than the other lines. +EOT + +my $u1 = <<'EOT'; +# we iterate over all *.c files +for c in *.c do + # first we print the file name + echo $c + # calculate the base name + b=`basename $c .c` + # compile it + gcc -o $b.o -c $c +done +EOT + +my $u2 = <<'EOT'; +for c in *.c do + # calculate the base name + b=`basename $c .c` + # compile it and print success message + gcc -o $b.o -c $c && echo "$c compiled OK" +done +EOT + +my @tests = ( + sub { t $t1, $t2, 0, <<"EOT" ++--+-------------------------------------------------------------+-------------------------------------------------------------------+ +| 1|This is |This is | +| 2|some text |some text | +* 3|that has a line which is quite longer than the other lines. |that has another line which is quite longer than the other lines. * ++--+-------------------------------------------------------------+-------------------------------------------------------------------+ +EOT + }, + sub { t $t1, $t2, 40, <<"EOT" ++--+----------------+-----------------+ +| 1|This is |This is | +| 2|some text |some text | +* 3|that has a line>|that has another>* ++--+----------------+-----------------+ +EOT + }, + sub { t $u1, $u2, 0, <<'EOT' ++--+----------------------------------+--+----------------------------------------------+ +* 1|# we iterate over all *.c files * | | +| 2|for c in *.c do | 1|for c in *.c do | +* 3| # first we print the file name * | | +* 4| echo $c * | | +| 5| # calculate the base name | 2| # calculate the base name | +| 6| b=`basename $c .c` | 3| b=`basename $c .c` | +* 7| # compile it * 4| # compile it and print success message * +* 8| gcc -o $b.o -c $c * 5| gcc -o $b.o -c $c && echo "$c compiled OK" * +| 9|done | 6|done | ++--+----------------------------------+--+----------------------------------------------+ +EOT + }, + sub { t $u1, $u2, 60, <<'EOT' ++--+---------------------+--+-----------------------------+ +* 1|# we iterate over al>* | | +| 2|for c in *.c do | 1|for c in *.c do | +* 3| # first we print t>* | | +* 4| echo $c * | | +| 5| # calculate the ba>| 2| # calculate the base name | +| 6| b=`basename $c .c` | 3| b=`basename $c .c` | +* 7| # compile it * 4| # compile it and print suc>* +* 8| gcc -o $b.o -c $c * 5| gcc -o $b.o -c $c && echo >* +| 9|done | 6|done | ++--+---------------------+--+-----------------------------+ +EOT + } +) ; + +plan tests => scalar @tests ; + +$_->() for @tests ;
From: ddascalescu+perl [...] gmail.com
On Mon Sep 05 03:48:22 2005, MAREKR wrote: Show quoted text
> The attached patch implements a WIDTH option for Text::Diff::Table > in order to limit the total table width to a given number of > characters (e.g. the terminal width). Please feel free to review > and/or adapt this patch according to your style,
Thanks for the patch. It looks like for lines that differ only after the more characters than roughly half the width, there will be no visible difference shown, other than the '*'. I've added an improvement to wrap longer lines, so that the difference in the case above will be shown on a continuation line. Show quoted text
> I'd be happy to see the feature in a new release of Text-Diff.
I just got co-maintenance of this module and will be pushing a new version today. Dan