make some progress, also make perl -cw work
[scpubgit/stemmatology.git] / lib / Text / Tradition / Collation.pm
CommitLineData
dd3b58b0 1package Text::Tradition::Collation;
d047cd52 2
3use Graph::Easy;
dd3b58b0 4use Moose;
5
6has 'graph' => (
d047cd52 7 is => 'ro',
8 isa => 'Graph::Easy',
9 handles => {
10 add_node => 'add_reading',
11 del_node => 'del_reading',
12 add_edge => 'add_path',
13 del_edge => 'del_path',
14 nodes => 'readings',
15 edges => 'paths',
16 },
17 default => sub { Graph::Easy->new( undirected => 0 ) },
18 );
784877d9 19
dd3b58b0 20
dd3b58b0 21has 'tradition' => (
d047cd52 22 is => 'ro',
23 isa => 'Text::Tradition',
24 );
dd3b58b0 25
26# The collation can be created two ways:
27# 1. Collate a set of witnesses (with CollateX I guess) and process
28# the results as in 2.
29# 2. Read a pre-prepared collation in one of a variety of formats,
30# and make the graph from that.
31
32# The graph itself will (for now) be immutable, and the positions
33# within the graph will also be immutable. We need to calculate those
34# positions upon graph construction. The equivalences between graph
35# nodes will be mutable, entirely determined by the user (or possibly
36# by some semantic pre-processing provided by the user.) So the
37# constructor should just make an empty equivalences object. The
38# constructor will also need to make the witness objects, if we didn't
39# come through option 1.
40
d047cd52 41sub BUILD {
42 my( $self, $args ) = @_;
43
44 # Call the appropriate parser on the given data
45 my @formats = grep { /^(GraphML|CSV|CTE|TEI)$/ } keys( %$args );
46 my $format = shift( @formats );
47 unless( $format ) {
48 warn "No data given to create a graph; will initialize an empty one";
49 }
50 if( $format =~ /^(CSV|CTE)$/ && !exists $args->{'base'} ) {
51 warn "Cannot make a graph from $format without a base text";
52 return;
53 }
54
55 # Initialize our graph object.
56 $self->graph->set_attribute( 'node', 'shape', 'ellipse' );
57 # Starting point for all texts
58 my $last_node = $self->graph->add_node( '#START#' );
59
60 # Now do the parsing.
61 my @sigla;
62 if( $format ) {
63 my @parseargs;
64 if( $format =~ /^(CSV|CTE)$/ ) {
65 @parseargs = ( 'base' => $args->{'base'},
66 'data' => $args->{$format},
67 'format' => $format );
68 $format = 'BaseText';
69 } else {
70 @parseargs = ( $args->{ $format } );
71 }
72 my $mod = "Text::Tradition::Parser::$format";
73 load( $mod );
74 # TODO parse needs to return witness IDs
75 @sigla = $mod->can('parse')->( $self->graph, @parseargs );
76 }
77
78 # Do we need to initialize the witnesses?
79 unless( $args->{'have_witnesses'} ) {
80 # initialize Witness objects for all our witnesses
81 my @witnesses;
82 foreach my $sigil ( @sigla ) {
83 push( @witnesses, Text::Tradition::Witness->new( 'sigil' => $sigil ) );
84 }
85 $self->tradition->witnesses( \@witnesses );
86 }
87}
784877d9 88
89# Wrappers around some methods
90
91sub merge_readings {
92 my $self = shift;
93 my $first_node = shift;
94 my $second_node = shift;
95 $first_node->merge_from( $second_node );
96 unshift( @_, $first_node, $second_node );
97 return $self->graph->merge_nodes( @_ );
98}
99
dd3b58b0 100no Moose;
101__PACKAGE__->meta->make_immutable;