Start fleshing out some of these classes
[scpubgit/stemmatology.git] / lib / Text / Tradition.pm
1 package Text::Tradition;
2
3 use Text::Tradition::Witness;
4 use Text::Tradition::Collation;
5 use Moose;
6
7 has 'collation' => (
8                     is => 'ro',
9                     isa => 'Text::Tradition::Collation',
10                     );
11
12 has 'witnesses' => (
13                     traits => ['Array'],
14                     is => 'rw',
15                     isa => 'ArrayRef[Text::Tradition::Witness]',
16                     handles => {
17                         all_options    => 'elements',
18                         add_option     => 'push',
19                         map_options    => 'map',
20                         option_count   => 'count',
21                         sorted_options => 'sort',
22                     },
23                     );
24
25 around BUILDARGS => sub {
26     my $orig = shift;
27     my $class = shift;
28
29     # Now @_ contains the original constructor args.  Make a
30     # collation argument and a witnesses argument.
31     my %init_args = @_;
32     my %member_objects = { 'collation' => undef,
33                            'witnesses' => [] };
34
35     if( exists $init_args{'witnesses'} ) {
36         # We got passed an uncollated list of witnesses.  Make a
37         # witness object for each witness, and then send them to the
38         # collator.
39         my $autosigil = 0;
40         foreach my $wit ( %{$init_args{'witnesses'}} ) {
41             # Each item in the list is either a string or an arrayref.
42             # If it's a string, it is a filename; if it's an arrayref,
43             # it is a tuple of 'sigil, file'.  Handle either case.
44             my $args;
45             if( ref( $wit ) eq 'ARRAY' ) {
46                 $args = { 'sigil' => $wit->[0],
47                           'file' => $wit->[1] };
48             } else {
49                 $args = { 'sigil' => chr( $autosigil+65 ),
50                           'file' => $wit };
51                 $autosigil++;
52             }
53             push( @{$member_objects{'witnesses'}},
54                   Text::Tradition::Witness->new( $args ) );
55             # Now how to collate these?
56         }
57     } else {
58         $member_objects{'collation'} = 
59             Text::Tradition::Collation->new( %init_args );
60         @{$member_objects{'witnesses'}} = 
61             $member_objects->{'collation'}->create_witnesses();
62     }
63
64     return $class->$orig( %member_objects );
65 };
66
67 # The user will usually be instantiating a Tradition object, and
68 # examining its collation.  The information about the tradition can
69 # come via several routes:
70 # - graphML from CollateX or elsewhere, standalone
71 # - TEI parallel segmentation
72 # - Leuven-style spreadsheet of variants, converted to CSV, plus base text
73 # - apparatus pulled from CTE, plus base text
74 # From this we should be able to get basic witness information.
75
76 # Alternatively the user can just give us the uncollated texts.  Then
77 # instead of passing a collation, s/he is passing a set of witnesses
78 # from which we will generate a collation.  Those witnesses can be in
79 # plaintext or in TEI with certain constraints adopted.
80
81 # So the constructor for a tradition needs to take one of these infosets,
82 # and construct the collation and the witness objects.
83
84 no Moose;
85 __PACKAGE__->meta->make_immutable;