X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FText%2FTradition.pm;h=9f7a3347b61afd97098c5277d410b42d4e56a865;hb=9463b0bff2afe6185d9bdfda49ce9c9cdc176049;hp=5f8d08059d36a5e33ea218a6bc88c5fea8804dfa;hpb=dd3b58b01da8319a3e3cc31e8f99a25be101cf05;p=scpubgit%2Fstemmatology.git diff --git a/lib/Text/Tradition.pm b/lib/Text/Tradition.pm index 5f8d080..9f7a334 100644 --- a/lib/Text/Tradition.pm +++ b/lib/Text/Tradition.pm @@ -1,27 +1,115 @@ -#!/usr/bin/env perl - package Text::Tradition; +use Module::Load; use Moose; +use Text::Tradition::Collation; +use Text::Tradition::Witness; has 'collation' => ( - is => 'ro', - isa => 'Text::Tradition::Collation', - init_arg => undef, - ); + is => 'ro', + isa => 'Text::Tradition::Collation', + writer => '_save_collation', + ); has 'witnesses' => ( - traits => ['Array'], - is => 'rw', - isa => 'ArrayRef[Text::Tradition::Witness]', - handles => { - all_options => 'elements', - add_option => 'push', - map_options => 'map', - option_count => 'count', - sorted_options => 'sort', - }, - ); + traits => ['Array'], + is => 'rw', + isa => 'ArrayRef[Text::Tradition::Witness]', + handles => { + all => 'elements', + add => 'push', + }, + default => sub { [] }, + ); + +has 'name' => ( + is => 'rw', + isa => 'Str', + default => 'Tradition', + ); + +sub BUILD { + my( $self, $init_args ) = @_; + + if( exists $init_args->{'witnesses'} ) { + # We got passed an uncollated list of witnesses. Make a + # witness object for each witness, and then send them to the + # collator. + my $autosigil = 0; + foreach my $wit ( %{$init_args->{'witnesses'}} ) { + # Each item in the list is either a string or an arrayref. + # If it's a string, it is a filename; if it's an arrayref, + # it is a tuple of 'sigil, file'. Handle either case. + my $args; + if( ref( $wit ) eq 'ARRAY' ) { + $args = { 'sigil' => $wit->[0], + 'file' => $wit->[1] }; + } else { + $args = { 'sigil' => chr( $autosigil+65 ), + 'file' => $wit }; + $autosigil++; + } + $self->witnesses->push( Text::Tradition::Witness->new( $args ) ); + # TODO Now how to collate these? + } + } else { + # Else we need to parse some collation data. Make a Collation object + my $collation = Text::Tradition::Collation->new( %$init_args, + 'tradition' => $self ); + $self->_save_collation( $collation ); + + # Call the appropriate parser on the given data + my @formats = grep { /^(Self|CollateX|CSV|CTE|TEI)$/ } keys( %$init_args ); + my $format = shift( @formats ); + unless( $format ) { + warn "No data given to create a collation; will initialize an empty one"; + } + if( $format && $format =~ /^(CSV|CTE)$/ && + !exists $init_args->{'base'} ) { + warn "Cannot make a collation from $format without a base text"; + return; + } + + # Starting point for all texts + my $last_node = $collation->add_reading( '#START#' ); + + # Now do the parsing. + my @sigla; + if( $format ) { + my @parseargs; + if( $format =~ /^(CSV|CTE)$/ ) { + $init_args->{'data'} = $init_args->{$format}; + $init_args->{'format'} = $format; + $format = 'BaseText'; + @parseargs = %$init_args; + } else { + @parseargs = ( $init_args->{ $format } ); + } + my $mod = "Text::Tradition::Parser::$format"; + load( $mod ); + $mod->can('parse')->( $self, @parseargs ); + } + } +} + +sub witness { + my( $self, $sigil ) = @_; + my $requested_wit; + foreach my $wit ( @{$self->witnesses} ) { + $requested_wit = $wit if $wit->sigil eq $sigil; + } + # We depend on an undef return value for no such witness. + # warn "No such witness $sigil" unless $requested_wit; + return $requested_wit; +} + + +sub add_witness { + my $self = shift; + my $new_wit = Text::Tradition::Witness->new( @_ ); + push( @{$self->witnesses}, $new_wit ); + return $new_wit; +} # The user will usually be instantiating a Tradition object, and # examining its collation. The information about the tradition can