use File::Which;
use Graph;
use IPC::Run qw( run binary );
-use Text::CSV_XS;
+use Text::CSV;
use Text::Tradition::Collation::Reading;
use Text::Tradition::Collation::RelationshipStore;
use Text::Tradition::Error;
has 'tradition' => (
is => 'ro',
isa => 'Text::Tradition',
+ writer => '_set_tradition',
weak_ref => 1,
);
throw( "Need GraphViz installed to output SVG" )
unless File::Which::which( 'dot' );
my $want_subgraph = exists $opts->{'from'} || exists $opts->{'to'};
- $self->calculate_ranks() unless $self->_graphcalc_done;
+ $self->calculate_ranks() unless( $self->_graphcalc_done || $opts->{'nocalc'} );
if( !$self->has_cached_svg || $opts->{'recalc'} || $want_subgraph ) {
my @cmd = qw/dot -Tsvg/;
my( $svg, $err );
return @wits;
}
+# Helper function. Make a display label for the given witnesses, showing a.c.
+# witnesses only where the main witness is not also in the list.
sub _path_display_label {
my $self = shift;
- my @wits = sort @_;
+ my %wits;
+ map { $wits{$_} = 1 } @_;
+
+ # If an a.c. wit is listed, remove it if the main wit is also listed.
+ # Otherwise keep it for explicit listing.
+ my $aclabel = $self->ac_label;
+ my @disp_ac;
+ foreach my $w ( sort keys %wits ) {
+ if( $w =~ /^(.*)\Q$aclabel\E$/ ) {
+ if( exists $wits{$1} ) {
+ delete $wits{$w};
+ } else {
+ push( @disp_ac, $w );
+ }
+ }
+ }
+
+ # See if we are in a majority situation.
my $maj = scalar( $self->tradition->witnesses ) * 0.6;
- if( scalar @wits > $maj ) {
- # TODO break out a.c. wits
- return 'majority';
+ if( scalar keys %wits > $maj ) {
+ unshift( @disp_ac, 'majority' );
+ return join( ', ', @disp_ac );
} else {
- return join( ', ', @wits );
+ return join( ', ', sort keys %wits );
}
}
sub as_csv {
my( $self ) = @_;
my $table = $self->alignment_table;
- my $csv = Text::CSV_XS->new( { binary => 1, quote_null => 0 } );
+ my $csv = Text::CSV->new( { binary => 1, quote_null => 0 } );
my @result;
# Make the header row
$csv->combine( map { $_->{'witness'} } @{$table->{'alignment'}} );
return @common;
}
-=head2 path_text( $sigil, $mainsigil [, $start, $end ] )
+=head2 path_text( $sigil, [, $start, $end ] )
Returns the text of a witness (plus its backup, if we are using a layer)
as stored in the collation. The text is returned as a string, where the
my( $self, $wit ) = @_;
my @chain = @{$wit->path};
my $sig = $wit->sigil;
+ # Add start and end if necessary
+ unshift( @chain, $self->start ) unless $chain[0] eq $self->start;
+ push( @chain, $self->end ) unless $chain[-1] eq $self->end;
foreach my $idx ( 0 .. $#chain-1 ) {
$self->add_path( $chain[$idx], $chain[$idx+1], $sig );
}
if( $wit->is_layered ) {
@chain = @{$wit->uncorrected_path};
+ unshift( @chain, $self->start ) unless $chain[0] eq $self->start;
+ push( @chain, $self->end ) unless $chain[-1] eq $self->end;
foreach my $idx( 0 .. $#chain-1 ) {
my $source = $chain[$idx];
my $target = $chain[$idx+1];